// This file is part of Timmi. // // Timmi is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. #include #include #include #include #include #include #include #include // 2 second delay for AI pickups const int AI_DELAY = 2000000; TimmiAI::TimmiAI(std::string name): TimmiClient(name) {} void TimmiAI::mainloop() { std::string line(""); while (good()) { wait_for_event(); while (socket_->getline(line)) { handle_line(line); } if (ingame_ && find_player(myid_).state == ACTIVE && status_valid_) { usleep(AI_DELAY); if (turn_ == myid_) { if (table_.size() != 0) { turn_beat(); } else { turn_hit(); } } else if (table_.size() != 0 && find_player(myid_).let_go_over == false) { turn_add(); } status_valid_ = false; // Prevent new AI-turns before status update } } } void TimmiAI::turn_hit() { if (hand_.size() == 0) { debug(WARNING, "Turn_hit with empty hand"); return; } std::vector::iterator iter = min_element(hand_.begin(), hand_.end(), CMPWorst(trump_.suit)); std::ostringstream msg(""); msg << "hit " << card_to_string(*iter); send_line(msg.str()); hand_.erase(iter); } void TimmiAI::turn_beat() { // Try to make sure that we beat by the worst cards std::sort(hand_.begin(), hand_.end(), CMPWorst(trump_.suit)); if (!can_beat_all(table_, hand_, trump_.suit)) { if (one_rank_only(table_, table_.at(0).tobeat.rank) && table_.size() + 1 <= next_turn_cardcount()) { int i; for (i = 0; i < hand_.size(); i++) { if (is_joker(hand_.at(i)) || hand_.at(i).rank == table_.at(0).tobeat.rank) { send_line("move " + card_to_string(hand_.at(i))); return; } } } // Could not beat nor move send_line("pickup"); return; } int t, h; for (t = 0; t < table_.size(); t++) { for (h = 0; h < hand_.size(); h++) { if (!is_card(table_.at(t).beater) && can_beat(table_.at(t).tobeat, hand_.at(h), trump_.suit)) { std::ostringstream msg(""); msg << "beat " << card_to_string(table_.at(t).tobeat); msg << " " << card_to_string(hand_.at(h)); send_line(msg.str()); break; } } } } void TimmiAI::turn_add() { std::vector options; int h; for (h = 0; h < hand_.size(); h++) { if (rank_exists_on_table(table_, hand_.at(h))) { options.push_back(hand_.at(h)); } } std::vector::iterator iter = min_element(options.begin(), options.end(), CMPWorst(trump_.suit)); if (iter == options.end() || (iter->suit == trump_.suit && decksize_ != 0) || (is_joker(*iter) && decksize_ != 0)) { if (all_beaten(table_)) { send_line("over"); } return; } // int i; // for (i = 0; i < options.size(); i++) { std::ostringstream msg(""); msg << "hit " << card_to_string(*iter); send_line(msg.str()); // } }