File indexing completed on 2024-11-24 03:43:17

0001 /*******************************************************************
0002 *
0003 * Copyright 2009  Pelladi Gabor <pelladigabor@gmail.com>
0004 *
0005 * Bovo is free software; you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation; either version 2, or (at your option)
0008 * any later version.
0009 *
0010 * Bovo is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with Bovo; see the file COPYING.  If not, write to
0017 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
0018 * Boston, MA 02110-1301, USA.
0019 *
0020 ********************************************************************/
0021 
0022 
0023 #include "aigabor.h"
0024 
0025 #include "coord.h"
0026 #include "dimension.h"
0027 #include "move.h"
0028 
0029 #include <QElapsedTimer>
0030 #include <QThread>
0031 #include <QtConcurrentRun>
0032 
0033 using namespace bovo;
0034 
0035 /** namespace for AI stuff */
0036 namespace ai {
0037 
0038 /**
0039  * @file aigabor.cc implementing the AiGabor class
0040  */
0041 
0042 AiGabor::AiGabor(const Dimension& dimension, KGameDifficultyLevel::StandardLevel skill,
0043        Player player) : m_player(player), m_minThink(200) {
0044     m_ai = new AiInterface();
0045     m_ai->setTableSizeX(dimension.width());
0046     m_ai->setTableSizeY(dimension.height());
0047     m_ai->setPrintInfo(false);
0048     m_ai->setTimeOver(this);
0049     setSkill(skill);
0050     m_ai->newGame();
0051     qRegisterMetaType<Move>("Move");
0052 }
0053 
0054 AiGabor::~AiGabor() {
0055     cancelAndWait();
0056     delete m_ai;
0057 }
0058 
0059 void AiGabor::cancelAndWait() {
0060     m_canceling = true;
0061     m_future.waitForFinished();
0062 }
0063 
0064 bool AiGabor::isTimeOver() {
0065     return m_canceling;
0066 }
0067 
0068 /* public slots */
0069 
0070 void AiGabor::changeBoard(const Move& move) {
0071     if (move.player() == No) {
0072         m_ai->undo();
0073     } else {
0074         m_ai->step(move.x(), move.y());
0075     }
0076 }
0077 
0078 void AiGabor::gameOver() {
0079 }
0080 
0081 void AiGabor::setSkill(KGameDifficultyLevel::StandardLevel skill) {
0082     switch (skill) {
0083         case KGameDifficultyLevel::RidiculouslyEasy: m_ai->setDepth(1); m_ai->setRandomAmount(10000); break;
0084         case KGameDifficultyLevel::VeryEasy: m_ai->setDepth(1); m_ai->setRandomAmount(9000); break;
0085         case KGameDifficultyLevel::Easy: m_ai->setDepth(1); m_ai->setRandomAmount(2000); break;
0086         case KGameDifficultyLevel::Medium: m_ai->setDepth(1); m_ai->setRandomAmount(2); break;
0087         case KGameDifficultyLevel::Hard: m_ai->setDepth(2); m_ai->setRandomAmount(2); break;
0088         case KGameDifficultyLevel::VeryHard: m_ai->setDepth(3); m_ai->setRandomAmount(2); break;
0089         case KGameDifficultyLevel::ExtremelyHard: m_ai->setDepth(6); m_ai->setRandomAmount(2); break;
0090         case KGameDifficultyLevel::Impossible: m_ai->setDepth(10); m_ai->setRandomAmount(2); break;
0091         default: break;
0092     }
0093 }
0094 
0095 void AiGabor::slotMove() {
0096     if (!m_future.isFinished()) {
0097         qFatal("Concurrent AI error");
0098     }
0099     m_canceling = false;
0100     m_future = QtConcurrent::run([this] { slotMoveImpl(); });
0101 }
0102 
0103 void AiGabor::slotMoveImpl() {
0104     QElapsedTimer time;
0105     time.start();
0106     Field f = m_ai->think();
0107     for (;;) {
0108         int elapsed = time.elapsed();
0109         if (elapsed >= m_minThink) {
0110             break;
0111         }
0112         QThread::yieldCurrentThread();
0113     }
0114     if (!m_canceling) {
0115         Q_EMIT move(Move(m_player, Coord(f.x, f.y)));
0116     }
0117 }
0118 
0119 } /* namespace ai */
0120 
0121 #include "moc_aigabor.cpp"