void gameLoop() { int curPlayer = connA; //socket for the current player /* * Board represents the curent state of the pegs in the board * Each digit corresponds to the number of pegs in that digits row * i.e. Row 1 has 1 peg, row 2 has 3 pegs, etc. * 9 is prepended to ensure the number always has 5 digits, but is not used */ int board = 91357; while(1) { //send Board to player char c = 'B'; write(curPlayer, &c, 1); char boardChar[6]; sprintf(boardChar, "%d", board); int left = strlen(boardChar); int put = 0; int num; while (left > 0) { if ((num = write(curPlayer, boardChar + put, left)) < 0) { perror("nim_server:write"); exit(0); } else { left -= num; } put += num; } c = ';'; write(curPlayer, &c, 1); //Read player's move char buffer[3]; c = '0'; read(curPlayer, &c, 1); //Get Type if (c != 'M') { fprintf(stderr, "nim_match:invalid message type %c\n", c); winGame(switchPlayer(curPlayer)); } read(curPlayer, buffer, 1); //read the move TODO: validate in case of network corruption read(curPlayer, buffer + 1, 1); read(curPlayer, &c, 1); if (c != ';') { fprintf(stderr, "nim_match:invalid move\n"); winGame(switchPlayer(curPlayer)); } board = updateBoard(board, buffer); if (board == 90000) { winGame(switchPlayer(curPlayer)); } curPlayer = switchPlayer(curPlayer); } }
void Board::checkEvents(sf::Event *event) { if(match != -1) { if(event->Type == sf::Event::KeyPressed) { if(event->Key.Code == sf::Key::Y) { gameReset(); } else if(event->Key.Code == sf::Key::N) { window->Close(); } } } else { if((event->Type == sf::Event::MouseButtonPressed) && (event->MouseButton.Button == sf::Mouse::Left)) { short xy = getXRegion(event->MouseButton.X) + BOARD_HEIGHT * getYRegion(event->MouseButton.Y); if(board[xy] == B) { board[xy] = player; if(checkWinCondition() == 0) { switchPlayer(); } else { gameMatch(); } } } } }
/** * Runs AI turn */ int aiTurn(ticTacToeBoard* selector, unsigned short int* corners, unsigned short int* sides, unsigned short int center, unsigned short int win, char* charPtr, unsigned short int* intPtr) { int defense = 1; // Checks difficulty chosen when setting up game switch(intPtr[2]) { case 1: noviceAI(charPtr); break; case 2: intermediateAI(selector, charPtr, defense); break; case 3: expertAI(selector, corners, sides, center, charPtr, intPtr, defense); break; } // Checks if winning position if(winPositionInfo(selector, charPtr)) return 1; //Switches player switchPlayer(charPtr); printf("\n\n"); return 0; }
/** * Finds a winning move for AI */ int findWinningMove(ticTacToeBoard* selector, char* charPtr, int defense) { char testPosition[10]; int i; int test; for(i = 0; i < 9; i++) { if(charPtr[30 + i] == ' ') { strcpy(testPosition, selector->rawData); testPosition[i] = charPtr[40]; test = 1; if(isWinningPosition(selector, charPtr, testPosition, test)) { if(defense == 1) switchPlayer(charPtr); test = 0; charPtr[30 + i] = charPtr[40]; return i; } } } return 10; }
/** * AI checks for win and returns position value */ int aiCheckWin(ticTacToeBoard* selector, char* charPtr, int defense) { int play; // Aggressive check defense = 0; // Resets win detector play = 0; //Checks if AI can win. Play if true play = findWinningMove(selector, charPtr, defense); if(play != 10){ return play; } // Switches player to check if they can win switchPlayer(charPtr); // Defensive check defense = 1; // Checks if user can win. Counter if true play = findWinningMove(selector, charPtr, defense); if(play != 10){ return play; } // Switches to AI charPtr[40] = charPtr[42]; return 20; }
void UserControl::ballHandlerSwitch () { Player *temp = team->getBallHolder(); if (team->getTeamHasBall()) while (temp != curPlayer && team->getTeamHasBall ()) { switchPlayer (); team->setTeamHasBall (); } }
void GameEngine::nextTurn() { switch (currentGameState) { case GS_PUT_FIRST_CHIP: { switchPlayer(); break; } case GS_PUT_SECOND_CHIP: { switchPlayer(true); break; } case GS_PUT_FIRST_ROAD: case GS_PUT_SECOND_ROAD: break; default: switchPlayer(); } }
void battleLocalWindow::nextTurn(){ switchPlayer(); if(CurrentPlayer == 1){ EnemyBoard = Player2Board; PlayerBoard = Player1Board; } else{ EnemyBoard = Player1Board; PlayerBoard = Player2Board; } printBoardText(PlayerBoard,ui->PlayerGameBoard, TRUE); //Player's Board printBoardText(EnemyBoard,ui->OpponentGameBoard, FALSE); //Opponent's Board }
void TicTacToe::on_buttonNewGame_clicked() { QListIterator<QAbstractButton *> i(gameField->buttons()); while (i.hasNext()) { QAbstractButton *qab = i.next(); qab->setEnabled(true); qab->setIcon(QIcon()); qab->setWhatsThis(""); } buttonNewGame->setEnabled(false); switchPlayer(); }
void game::update() { m_isWon = checkWin(); m_isDraw = checkDraw(); m_isComplete = (m_isDraw || m_isWon); if (!m_isComplete) { cout << "Computer: Your move?...\t"; m_invalidInput = m_b.update(m_currPlayer->getMove(),m_currPlayer->GetIcon()); while (!m_invalidInput) { cout << "Invalid move, please try again: "; m_invalidInput = m_b.update(m_currPlayer->getMove(),m_currPlayer->GetIcon()); } switchPlayer(); } else if (m_isWon){ switchPlayer(); cout << "You win!!! " <<m_currPlayer->GetName() << " ("<<m_currPlayer->GetIcon() << ")\n"<<endl; switchPlayer(); cout <<m_currPlayer->GetName() << " ("<<m_currPlayer->GetIcon() << ")" << " is defeated."<<endl; } else if (m_isDraw) cout << "\n\n\nIt's a draw" <<endl; }
/** * Runs user turn */ int userTurn(ticTacToeBoard* selector, unsigned short int win, char* charPtr, unsigned short int aiPlay) { int i = 0; int playSpace = 0; renderBoard(charPtr, win); while(i == 0) { if(aiPlay == 1) printf(" Please choose a space to play.\n"); else printf(" Player %c: Please choose a space to play.\n", charPtr[40]); printf("\n 0 1 2"); printf("\n 3 4 5"); printf("\n 6 7 8\n\n"); printf("Selection: "); scanf("%i", &playSpace); printf("\n"); if(((int)playSpace >= 0) && ((int)playSpace <= 8)) { if(charPtr[30 + playSpace] == ' ') { charPtr[30 + playSpace] = charPtr[40]; i++; } else { printf(" This space is already occupied. Try again.\n"); renderBoard(charPtr, win); } } else { printf(" *Invalid input. Try again*\n"); renderBoard(charPtr, win); } } // Checks if winning position if(winPositionInfo(selector, charPtr)) return 1; // Switches player switchPlayer(charPtr); printf("\n\n"); return 0; }
void Scene::undoMove() { board->playHistory.pop_back(); if (gameMode == PVC) //if in PVC, got to clear computer move as well board->playHistory.pop_back(); board->boardRepresentation = board->previousBoard; if (gameMode == PVP) switchPlayer(); //if in PVC, player is always the same else updateGameMessage(); gameState = PLACEPIECE; ((Interface *)iface)->undo->disable(); }
void Board::switchPlayer() { (player == O) ? (player = X) : (player = O); // Run AI. if(player == ai->getPiece()) { ai->run(board); if(checkWinCondition() == 0) { switchPlayer(); } else { gameMatch(); } } }
bool PlayerManager::sendInput(Player* player, int position) { bool valid = controller->makeMove(player == playerA ? 1 : 2, position); // If we're not playing anymore, return true and dont switch players if (controller->getState() != Controller::State::Playing) { return true; } if (valid) { switchPlayer(); notifyOther(position); return true; } return false; }
void TicTacToe::on_gameField_buttonClicked(QAbstractButton *button) { switch(_currPlayer) { case 1: button->setIcon(QPixmap::fromImage(*_player1)); button->setWhatsThis("1"); break; case 2: button->setIcon(QPixmap::fromImage(*_player2)); button->setWhatsThis("2"); break; } button->setEnabled(false); bool won = checkWin(); if(won || full()) { if(won) { QListIterator<QAbstractButton *> i(gameField->buttons()); while (i.hasNext()) { QAbstractButton *qab = i.next(); qab->setEnabled(false); } switch(_currPlayer) { case 1: scorePlayer1->setText(QString::number(++_score1)); printInfo("Player 1 wins!"); break; case 2: scorePlayer2->setText(QString::number(++_score2)); printInfo("Player 2 wins!"); break; } } turnPlayer1->setText(""); turnPlayer2->setText(""); buttonNewGame->setEnabled(true); } else { switchPlayer(); } }
void Scene::rotateQuadrant(int quadrant, int direction) { if (gameState == ROTATE) { board->playHistory.back().at(1) = quadrant; board->playHistory.back().at(2) = direction; board->rotateQuadrant(socket, quadrant, direction); checkVictory(); if (gameState != GAMEOVER) { if (gameMode == PVC) computerPlay(); else switchPlayer(); } } }
void UserControl::cycleStates() { checkInput (); if (curMovement != NO_INPUT) movePlayer (); if (switchTimer->isTime()) { if (curAction == SWITCH) switchPlayer (); else if( curAction == GOAL_KICK || curAction == PASS_KICK) if( curPlayer->playerHasBall()) kickBall (); } }
void Scene::computerPlay() { if (!computerPlaying) { player = !player; updateGameMessage(); board->computerPlacePiece(socket); checkVictory(); if (gameState == GAMEOVER) //if someone won, dont do anything else return; computerPlaying = true; //wait for animation to end to do rotation return; } else { board->computerRotateQuadrant(socket); computerPlaying = false; checkVictory(); if (gameState != GAMEOVER) switchPlayer(); } }
int makeMove(const char *move) { int col, row, neighbor; char direction; int ohs_up = 0, ohs_down = 0, ohs_right = 0, ohs_left = 0, eks_up = 0, eks_down = 0, eks_right = 0, eks_left = 0; if (current.gameOver != NOPLAYER); /* Game is over */ if (current.boardEmpty) { if (!strcmp(move, "@0/")) { putAt(1, 1, NW); switchPlayer(); return 0; } if (!strcmp(move, "@0+")) { putAt(1, 1, NS); switchPlayer(); return 0; } } /* parse move string */ getTraxMoveDefinition(&row, &col, move, &direction); if (col == 0 && row == 0) return -1; /* No neighbours */ if ((row == 0) && (!canMoveDown())) return -1; /* illegal row */ if ((col == 0) && (!canMoveRight())) return -1; /* illegal column */ if (!isBlank(row, col)) return -1; /* occupy */ char up = getAt(row - 1, col); char down = getAt(row + 1, col); char left = getAt(row, col - 1); char right = getAt(row, col + 1); if (up == SN || up == SE || up == SW) ohs_up = 1; if (up == EW || up == NW || up == NE) eks_up = 1; if (down == NS || down == NE || down == NW) ohs_down = 1; if (down == EW || down == SW || down == SE) eks_down = 1; if (left == EN || left == ES || left == EW) ohs_left = 1; if (left == WS || left == WN || left == NS) eks_left = 1; if (right == WN || right == WE || right == WS) ohs_right = 1; if (right == ES || right == NS || right == EN) eks_right = 1; neighbor = ohs_up + (2 * ohs_down) + (4 * ohs_left) + (8 * ohs_right) + (16 * eks_up) + (32 * eks_down) + (64 * eks_left) + (128 * eks_right); switch (neighbor) { case 0: /* no neighbor error */ return -1; case 1: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 2: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 4: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 8: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, EW); break; default: /* This should never happen */ break; } break; case 16: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 18: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': return -1; default: /* This should never happen */ break; } break; case 20: switch (direction) { case '/': return -1; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 24: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': return -1; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 32: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 33: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': return -1; default: /* This should never happen */ break; } break; case 36: switch (direction) { case '/': putAt(row, col, NW); break; case '+': putAt(row, col, WE); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 40: switch (direction) { case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, EW); break; case '/': return -1; default: /* This should never happen */ break; } break; case 64: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 65: switch (direction) { case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, NS); break; case '/': return -1; default: /* This should never happen */ break; } break; case 66: switch (direction) { case '/': putAt(row, col, SE); break; case '+': putAt(row, col, SN); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 72: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': return -1; default: /* This should never happen */ break; } break; case 128: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 129: switch (direction) { case '/': putAt(row, col, NW); break; case '+': putAt(row, col, NS); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 130: switch (direction) { case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, SN); break; case '/': return -1; default: /* This should never happen */ break; } break; case 132: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': return -1; default: /* This should never happen */ break; } break; default: /* This should never happen */ break; } if (row == 0) row++; if (col == 0) col++; if (!forcedMove(row - 1, col)) { return -1; } if (!forcedMove(row + 1, col)) { return -1; } if (!forcedMove(row, col - 1)) { return -1; } if (!forcedMove(row, col + 1)) { return -1; } /* note that switchPlayer() _must_ come before isGameOver() */ switchPlayer(); /* updates the gameOver attribute */ isGameOver(); return 0; }
/// Returns the best available move for \a player according to evaluateBoard() /// after considering a search tree of depth \a depth. /// /// Precondition for outside callers: \a depth >= 1 std::pair<Candidate, bool> Opponent::bestMove(Board const& board, int depth, Square player, QElapsedTimer const& timer) { assert(depth > 0); if (timer.elapsed() > timeOut) { return std::make_pair(Candidate{}, true); } if (player == O) { // try every move and use the best one Point move; Score score = -std::numeric_limits<Score>::max(); for (int r = 0; r != board.rows(); ++r) { for (int c = 0; c != board.rows(); ++c) { if (board(r, c) == Blank) { Board future{board}; future(r, c) = player; Score futureScore; if (depth == 1 || future.full()) { // we're not going to look further or there's no further to look futureScore = evaluateBoard(future); } else { std::pair<Candidate, bool> result = bestMove(future, depth - 1, switchPlayer(player), timer); if (result.second == true) { // time out return result; } futureScore = result.first.score; } if (futureScore > score) { move = Point{r, c}; score = futureScore; } else if (futureScore == score) { // prefer central squares when scores are equal if (distanceToCenter(move, board.rows()) > distanceToCenter(Point{r, c}, board.rows())) { move = Point{r, c}; score = futureScore; } } } // if we have won, there's no point looking for better moves if (score > winScore) { return std::make_pair(Candidate{move, score}, false); } } } return std::make_pair(Candidate{move, score}, false); } else if (player == X) { // player is expected to pick the worst move from O's perpective Point move; Score score = std::numeric_limits<Score>::max(); for (int r = 0; r != board.rows(); ++r) { for (int c = 0; c != board.rows(); ++c) { if (board(r, c) == Blank) { Board future{board}; future(r, c) = player; Score futureScore; if (depth == 1 || future.full()) { // we're not going to look further or there's no further to look futureScore = evaluateBoard(future); } else { std::pair<Candidate, bool> result = bestMove(future, depth - 1, switchPlayer(player), timer); if (result.second == true) { // time out return result; } futureScore = result.first.score; } if (futureScore < score) { move = Point{r, c}; score = futureScore; } else if (futureScore == score) { // expect player to prefer central squares when scores are equal if (distanceToCenter(move, board.rows()) > distanceToCenter(Point{r, c}, board.rows())) { move = Point{r, c}; score = futureScore; } } // if player has won, there's no point looking for worse moves if (score < -winScore) { return std::make_pair(Candidate{move, score}, false); } } } } return std::make_pair(Candidate{move, score}, false); } else { assert(false); } }
/** * Expert: Intermediate but plays corner first and counters a corner with center */ int expertAI(ticTacToeBoard* selector, unsigned short int* corners, unsigned short int* sides, unsigned short int center, char* charPtr, unsigned short int* intPtr, int defense) { // Looping variables int i; int k; // Random int to be set int random; int play; int emptySpaces[9]; // If play is greater than or equal to 3 if(intPtr[0] >= 3){ // Check if AI wins with given play play = aiCheckWin(selector, charPtr, defense); if(play==20){ // Set player back to AI charPtr[40] = charPtr[42]; //Fills all empty positions into array of integers for(i = 0; i < 9; i++) { if(charPtr[30 + i] == ' ') { emptySpaces[k] = i; k++; } } // Sets new seed srand(time(NULL)); // Rolls random int random = rand() % k; random = emptySpaces[random]; //Pulls a random int from array and plays in that position charPtr[30 + random] = charPtr[40]; play = random; } } if(intPtr[0] == 2){ play = 0; // Switches player to check their move switchPlayer(charPtr); for(i = 0; i < 4; i++) { // If user plays corner, play center if((charPtr[30 + corners[i]] == charPtr[40]) || (charPtr[30 + sides[i]] == charPtr[40]) && (charPtr[30 + center] == ' ')) { // Switches to AI to counter move switchPlayer(charPtr); charPtr[30 + center] = charPtr[40]; play = center; } } if(play == 0){ // Set player back to AI charPtr[40] = charPtr[42]; //Fills all empty positions into array of integers for(i = 0; i < 9; i++) { if(charPtr[30 + i]==' '){ emptySpaces[k] = i; k++; } } // Sets new seed srand(time(NULL)); // Rolls random int random = rand() % k; random = emptySpaces[random]; //Pulls a random int from array and plays in that position charPtr[30 + random] = charPtr[40]; play = random; switchPlayer(charPtr); } } else if(intPtr[0] == 1){ play = startingPosition(charPtr,corners); } printf("\n **AI played position %i**\n", play); return 0; }