bool AI::makeMove(SDL_Event *event){ // Init enemyTeam that this class can use getEnemyTeam(); for(int index=0;index<team.size();index++){ currentIndex = index; team[index].directionValues[0] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, LEFT); team[index].directionValues[1] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, RIGHT); if (team[index].isKing()) { team[index].directionValues[3] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, BACK_RIGHT); team[index].directionValues[2] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, BACK_LEFT); } cout<<"Index: "<<index<<" ("<< team[index].x << "," << team[index].y; cout<<") Left: "<<team[index].directionValues[0]<<" Right: "<<team[index].directionValues[1]; cout<<" bLeft: "<<team[index].directionValues[2]<<" bRight: "<<team[index].directionValues[3]<<endl; team[index].findBestDirection(); team[index].findLargestPotenial(); } int bestPieceIndex = bestPiece(team); cout<< "The chosen one: " << bestPieceIndex << " -> ("<< team[bestPieceIndex].x << "," << team[bestPieceIndex].y; int x = team[bestPieceIndex].x; int y = team[bestPieceIndex].y; // Makes sure the move isnt out of bounds // if (team[bestPieceIndex].potential != OUT_OF_BOUND) { changeWithDirection(x, y, team[bestPieceIndex].bestDirection, false); if(sameTeam(Board->virtualBoard[x][y],ENEMY_TEAM_NUMBER)){ // Changes it again for moving 2 units diagonally // changeWithDirection(x, y, team[bestPieceIndex].bestDirection, false); } cout<<") best move: (" << x << "," << y <<")"<< endl; movePiece(Board->virtualBoard, team, bestPieceIndex, x, y); return true; } return false; }
int AI::minMove(vector<vector<int>> tempboard, vector<Piece> teamCopy, vector<Piece> enemyTeamCopy, int depth){ for(int index=0;index<enemyTeamCopy.size();index++){ enemyCurrentIndex = index; enemyTeamCopy[index].directionValues[0] = minValue(tempboard, teamCopy, enemyTeamCopy, depth, LEFT); enemyTeamCopy[index].directionValues[1] = minValue(tempboard, teamCopy, enemyTeamCopy, depth, RIGHT); if (enemyTeamCopy[index].isKing()) { enemyTeamCopy[index].directionValues[3] = minValue(tempboard, teamCopy, enemyTeamCopy, depth, BACK_RIGHT); enemyTeamCopy[index].directionValues[2] = minValue(tempboard, teamCopy, enemyTeamCopy, depth, BACK_LEFT); } enemyTeamCopy[index].findLargestPotenial(); } int bestPieceIndex = bestPiece(enemyTeamCopy); return enemyTeamCopy[bestPieceIndex].potential; }
void Game::play() { long maxp = gameSettings->getMaxp(); long maxl = gameSettings->getMaxl(); long maxg = gameSettings->getMaxg(); int level = gameSettings->getLevel(); int preview = gameSettings->getPreview(); int stat = gameSettings->getStat(); int size = gameSettings->getSize(); int sliding = gameSettings->getSliding(); int delay = gameSettings->getDelay(); int animate = gameSettings->getAnimate(); int exit = gameSettings->getExit(); int pieceStartX = gameSettings->getPieceStartX(); int frameRateDelay = gameSettings->getFrameRateDelay(); int nextPiece = 0; int viewBoard = gameSettings->getViewBoard(); int stepMode = gameSettings->getStepMode(); milisec1 = GetTickCount(); milisec2 = GetTickCount(); seconds = time(NULL); if (strlen(gameSettings->getWgameFilename()) != 0) { if (wGameFile.open(gameSettings->getWgameFilename())) { cout << "Could not open the file \"" << gameSettings->getWgameFilename() << "\"" << endl; return; } } if (strlen(gameSettings->getRgameFilename()) != 0) { if (rGameFile.open(gameSettings->getRgameFilename())) { cout << "Could not open the file \"" << gameSettings->getRgameFilename() << "\"" << endl; return; } } if (strlen(gameSettings->getWhtmlFilename()) != 0) { wHtml.open(gameSettings->getWhtmlFilename()); if (!wHtml.good()) { cout << "Could not open the file \"" << gameSettings->getWhtmlFilename() << "\"" << endl; return; } } board = new Board(gameSettings->getWidth(), gameSettings->getHeight(), sliding, pieceStartX); Piece setStaticInitializersPiece(board, 1, sliding, 1); Player *player = new Player(board); Random random = Random(gameSettings->getSeed()); GameInfo gameInfo(maxCntblockstat); writeTmpFile(board); double equity = player->evaluate(); double maxDiff = 0; int pieces[10]; if (preview > 1) pieces[0] = random.getRandomP(); pieces[1] = 0; pieces[2] = 0; pieces[3] = 0; pieces[4] = 0; pieces[5] = 0; pieces[6] = 0; pieces[7] = 0; pieces[8] = 0; pieces[9] = 0; if (wGameFile.isOpen()) { // 1. Version of the file wGameFile.writeShort(1); // # Version (short) // 2. Header wGameFile.writeShort(DATA_HEADER); // # Type of block wGameFile.writeShort(1); // # Version wGameFile.writeShort(gameSettings->getWidth()); // # Width (short) wGameFile.writeShort(gameSettings->getHeight()); // # Height (short) wGameFile.writeInt(gameSettings->getSeed()); // # Seed (int) wGameFile.writeByte(gameSettings->getLevel()); // # Level (byte) wGameFile.writeByte(gameSettings->getPreview()); // # Preview (byte) wGameFile.writeByte(pieces[0]); // # Piece (byte) } while ((maxg==0 && maxl==0 && maxp==0) || ((maxg > 0 && games < maxg) || (maxl > 0 && totalLines < maxl) || (maxp > 0 && totalPieces < maxp))) { if (exit == 1 || gameSettings->getExit() == 1) break; //------------------------------------------- if (stepMode != gameSettings->getStepMode()) { stepMode = gameSettings->getStepMode(); initTime(); } if (level != gameSettings->getLevel()) { level = gameSettings->getLevel(); initTime(); } if (sliding != gameSettings->getSliding()) { sliding = gameSettings->getSliding(); board->setSliding(sliding); initTime(); } if (preview != gameSettings->getPreview()) { preview = gameSettings->getPreview(); if (preview == 1) pieces[1] = 0; else { if (nextPiece == 0) nextPiece = pieces[1] = random.getRandomP(); else pieces[1] = nextPiece; } initTime(); } if (animate != gameSettings->getAnimate()) { animate = gameSettings->getAnimate(); initTime(); } if (delay != gameSettings->getDelay()) { delay = gameSettings->getDelay(); initTime(); } if (frameRateDelay != gameSettings->getFrameRateDelay()) { frameRateDelay = gameSettings->getFrameRateDelay(); initTime(); } if (viewBoard != gameSettings->getViewBoard()) { viewBoard = gameSettings->getViewBoard(); initTime(); } while (gameSettings->isPause()) ::Sleep(10); if (board->getWidth() != gameSettings->getWidth()) { delete board; pieceStartX = gameSettings->getPieceStartX(); board = new Board(gameSettings->getWidth(), gameSettings->getHeight(), sliding, pieceStartX); Piece setStaticInitializersPiece(board, 1, sliding, 1); } //------------------------------------------- if (preview > 1) nextPiece = pieces[1] = random.getRandomP(); else pieces[0] = random.getRandomP(); if (wGameFile.isOpen()) wGameFile.writeByte(pieces[1]); // # Piece Piece bestPiece(board, pieces[0]); gameObserverList.notify(board, &gameInfo, pieces[0], pieces[1], 1, milisec1, milisec2, cntblockstat, games, cntPieces, cntLines, totalMoves, totalSlided, totalLines, totalLines2, totalPieces, totalPieces2, minLines, maxLines, linesPerGame); if (!animate) ::Sleep(delay*10); int playAgain; Move *bestMove; MoveList *moveList; do { playAgain = 0; gameSettings->setIsThinking(); if (animate != gameSettings->getAnimate()) { animate = gameSettings->getAnimate(); initTime(); } bestMove = player->play(pieces, level, preview, animate, &gameObserverList); if (bestMove > 0) bestPiece.set(bestMove->getV(), bestMove->getX(), bestMove->getY(), bestMove->getClearedLines()); gameSettings->setIsNotThinking(); moveList = board->getMoveList(level); gameObserverList.notify(moveList); while (gameSettings->isStepModeOn() && gameSettings->isStepWait()) { if (level != gameSettings->getLevel()) { level = gameSettings->getLevel(); initTime(); playAgain = 1; break; } if (preview != gameSettings->getPreview()) { preview = gameSettings->getPreview(); if (preview == 1) pieces[1] = 0; else { if (nextPiece == 0) nextPiece = pieces[1] = random.getRandomP(); else pieces[1] = nextPiece; } initTime(); playAgain = 1; gameObserverList.notify(board, &gameInfo, pieces[0], pieces[1], 1, milisec1, milisec2, cntblockstat, games, cntPieces, cntLines, totalMoves, totalSlided, totalLines, totalLines2, totalPieces, totalPieces2, minLines, maxLines, linesPerGame); break; } if (sliding != gameSettings->getSliding() && bestMove > 0) { sliding = gameSettings->getSliding(); board->setSliding(sliding); initTime(); playAgain = 1; break; } ::Sleep(10); } } while (playAgain); if (gameSettings->isStepModeOn()) gameSettings->setStepWait(); if (!animate && bestMove > 0) { bestPiece.setPiece(); if (bestPiece.getClearedLines() > 0) board->clearLines(bestPiece.getY(), bestPiece.getHeight()); } Move *move; int index = 0; int length = moveList->getLength(); totalMoves += length; if (animate && bestMove > 0) { // Animate the moves. MovePath *movePath = board->getMovePath(level); MovePathStep *s = movePath->getPath(bestMove->getV(), bestMove->getX(), bestMove->getY()); int skipFirst = 0; int prevy = -1; while (s > 0) { //---- // Calculate the number of steps for the current line (y value). MovePathStep *s1 = s; int y1 = s1->y; int cnt; if (prevy != y1) { cnt = 0; while (s1 > 0 && s1->y == y1) { cnt++; s1 = s1->next; } prevy = y1; } //---- if (animate != gameSettings->getAnimate()) break; if (delay != gameSettings->getDelay()) delay = gameSettings->getDelay(); int v = s->v; int x = s->x; int y = s->y; Piece piece(board, bestPiece.getP()); piece.setPiece(v, x, y); if (skipFirst) gameObserverList.notify(board, &gameInfo, pieces[0], pieces[1], 0, milisec1, milisec2, cntblockstat, games, cntPieces, cntLines, totalMoves, totalSlided, totalLines, totalLines2, totalPieces, totalPieces2, minLines, maxLines, linesPerGame); if (gameSettings->isSlidingOn()) ::Sleep((double)delay / cnt); else ::Sleep((double)delay); piece.clearPiece(); skipFirst = 1; s = s->next; while (gameSettings->isPause()) ::Sleep(10); } bestPiece.setPiece(); if (bestPiece.getClearedLines() > 0) { int clearedLinesBits = board->getClearedLines(bestPiece.getY(), bestPiece.getHeight()); for (int n=0; n<4; n++) { board->flashLines(bestPiece.getY(), bestPiece.getHeight(), clearedLinesBits); if (n<3) { gameObserverList.notify(board, &gameInfo, pieces[0], pieces[1], 0, milisec1, milisec2, cntblockstat, games, cntPieces, cntLines, totalMoves, totalSlided, totalLines, totalLines2, totalPieces, totalPieces2, minLines, maxLines, linesPerGame); if (delay > 0) { if (delay >= 50) ::Sleep(150); else ::Sleep(150-(50-delay)*2); } } } board->clearLines(bestPiece.getY(), bestPiece.getHeight()); } } cntPieces++; totalPieces++; if (bestMove > 0) totalSlided += bestMove->isSlided(); // Log the moves if (wGameFile.isOpen()) { wGameFile.writeShort(length); // # Number of legal moves. wGameFile.writeByte(bestPiece.getV()); // # V wGameFile.writeShort(bestPiece.getX()); // # X wGameFile.writeShort(bestPiece.getY()); // # Y move = moveList->getFirstMove(); while (move != 0) { // Move: wGameFile.writeByte(move->getV()); // # V wGameFile.writeShort(move->getX()); // # X wGameFile.writeShort(move->getY()); // # Y for (int i=preview; i<=level; i++) // Equity (e.g): wGameFile.writeFloat(move->getEquity(i)); // L2, L3, L4 move = moveList->getNextMove(); } } if (preview > 1) pieces[0] = pieces[1]; int clearedLines = bestPiece.getClearedLines(); if (bestMove == 0) { games++; linesPerGame = totalLines/games; } else { cntLines += clearedLines; totalLines += clearedLines; cntBlock += 4 - clearedLines * board->getWidth(); if (DEBUG == 0) { int xxx = cntBlock/4; if (xxx < maxCntblockstat) cntblockstat[xxx]++; } } if (cntLines > maxLines) maxLines = cntLines; if (bestMove == 0) { if (cntLines < minLines || minLines==-1) minLines = cntLines; cntBlock = 0; cntPieces = 0; cntLines = 0; board->clear(); pieces[0] = random.getRandomP(); } } delete board; delete player; if (wGameFile.isOpen()) { wGameFile.writeByte(END_PIECE); // # Piece wGameFile.close(); } if (rGameFile.isOpen() && strlen(gameSettings->getWhtmlFilename()) > 0) { readGame(maxp, size); rGameFile.close(); } gameSettings->setExit(2); }