Replay tic tac toe game - c++

So I am trying to program a way to replay a tic tac toe game after someone wins, loses, or ties.
So basically my attempt to get replay to work, doesnt work. If player 1 won and I type 1 to replay, it would ask player 2 for their input.
Pseudocode outline:
do {
set entire 2d array to '*'
do {
player 1 input
does game tie?
does player 1 win
player 2 input
does game tie?
does player 2 win
} while no one wins
} while replay = 1
My actual code:
//tie check, replay, use pointer notation
#include <iostream>
using namespace std;
void initialize(char [][3]);
void player1(char [][3]);
void player2(char [][3]);
void display(char [][3]);
char check(char [3][3]);
int checkWin(int);
int tie(int);
int askReplay();
int main()
{
char board[3][3];
char end = '*';
int row1, column1, row2,column2;
int replay = 0;
int turns = 0;
//replay loop
do {
//set board to *
initialize(board);
display(board);
do {
//player 1 turn
player1(board);
turns++;
display(board);
//if turns = 9 then tie
replay = tie(turns);
//check if player 1 won
end = check(board);
replay = checkWin(end);
//player 2 turn
player2(board);
turns++;
display(board);
//if turns = 9 then tie
replay = tie(turns);
//check if player 2 won
end = check(board);
replay = checkWin(end);
} while (end == '*');
} while (replay == 1);
return 0;
}
void initialize(char (*array)[3])
{
for (int i = 0;i < 3;i++)
for (int j = 0;j < 3;j++)
array[i][j] = '*';
cout << "New Game\n";
}
void player1(char (*array)[3])
{
int row1, column1;
cout << "Player 1\nRow: ";
cin >> row1;
while (row1 < 0 || row1 > 2) {
cout << "Enter a number between 0 and 2 for Row:: ";
cin >> row1;
}
cout << "Column: ";
cin >> column1;
while (column1 < 0 || column1 > 2) {
cout << "Enter a number between 0 and 2 for Column: ";
cin >> column1;
}
if (array[row1][column1] == '*')
array[row1][column1] = 'X';
else {
cout << "Space Occupied\n";
player1(array);
}
}
void player2(char (*array)[3])
{
int row2,column2;
cout << "Player 2\nRow: ";
cin >> row2;
while (row2 < 0 || row2 > 2) {
cout << "Enter a number between 0 and 2 for Row: ";
cin >> row2;
}
cout << "Column: ";
cin >> column2;
while (column2 < 0 || column2 > 2) {
cout << "Enter a number between 0 and 2 for Column: ";
cin >> column2;
}
if (array[row2][column2] == '*')
array[row2][column2] = 'O';
else {
cout << "Space Occupied\n";
player2(array);
}
}
void display(char (*array)[3])
{
for (int x = 0;x < 3;x++) {
for (int y = 0;y < 3;y++)
cout << *(*(array + x) + y) << " ";
cout << endl;
}
}
char check(char (*array)[3])
{
int i;
/* check rows */
for(i = 0; i < 3; i++)
if(array[i][0] == array[i][1] && array[i][0] == array[i][2])
return array[i][0];
/* check columns */
for(i = 0; i < 3; i++)
if(array[0][i] == array[1][i] && array[0][i] == array[2][i])
return array[0][i];
/* test diagonals */
if(array[0][0] == array[1][1] && array[1][1] == array[2][2])
return array[0][0];
if(array[0][2] == array[1][1] && array[1][1] == array[2][0])
return array[0][2];
return '*';
}
int checkWin(int over)
{
if (over == '*')
return 0;
if (over == 'X')
cout << "Player 1 Won!\n";
else if (over == 'O')
cout << "Player 2 Won!\n";
//ask if they want to play again
int answer;
answer = askReplay();
switch (answer) {
case 1:
return 1;
case 2:
cout << "Thank you for playing.\n";
exit(0);
}
}
int tie(int count)
{
if (count == 9) {
int answer;
cout << "Tie game";
answer = askReplay();
switch (answer) {
case 1:
return 1;
case 2:
cout << "Thank you for playing.\n";
exit(0);
}
}
}
int askReplay()
{
int input;
do {
cout << "Play Again?\n1.Yes\n2.No\nEnter 1 or 2: ";
cin >> input;
if (input > 2 || input < 1)
cout << "Invalid Option\n";
} while(input > 2 || input < 1);
return input;
}

It sounds like you're having troubles with your main loop.
I'd suggest making a variable that controls which player is running and just toggle that.
do
{
set entire 2d array to '*'
current player = 0
do
{
(current player + 1) input
does game tie?
does (current player + 1) win
current player = (current player + 1) % 2
}while no one wins
}while replay = 1
See if that gets you further along.

You may want to look up the Memento Design Pattern.

Related

Tic Tac Toe minimax algorithm in C++

Ive been learning C++ and I decided to make a tictactoe project that utilizes a MiniMax algorithm. I have made all the functionality for playing, including 2 player. Why doesn't my minimax algorithm when I choose to play with the AI work ? It always moves to 0 or 8 and I can't figure out why. Any help will be appreciated
TicTacToe.h
#ifndef TICTACTOE_TICTACTOEGAME_H
#define TICTACTOE_TICTACTOEGAME_H
#include <string>
#include <iostream>
#include <vector>
class TicTacToeGame {
struct move{
int score;
int index;
};
public:
const int PLAYER1_INDEX = 1;
const int PLAYER2_INDEX = 2;
const int AI_INDEX = 3;
TicTacToeGame();
void play(TicTacToeGame);
bool hasWon() const;
bool haveTied() const;
char getMarker(int, int) const;
void setMarker(int, int);
void resetMarker(int);
int getCurrentPlayer() const;
std::vector<int> possibleMoves();
private:
char board[3][3];
std::string player1_name;
std::string player2_name;
int currentPlayer;
bool isMultiplayer;
int moveCount = 0;
void init();
void printBoard();
void setPlayer1Name(std::string);
void setPlayer2Name(std::string);
std::string getPlayer1Name() const;
std::string getPlayer2Name() const;
void switchCurrentPlayer();
std::string winMessage();
int getRow(int) const;
int getColumn(int) const;
bool checkMarker(int, int);
void makeAIMove(TicTacToeGame);
move miniMax(TicTacToeGame, int);
};
#endif //TICTACTOE_TICTACTOEGAME_H
TicTacToe.cpp
#include "TicTacToeGame.h"
// Player is MINIMIZER, AI is MAXIMIZER
TicTacToeGame::move TicTacToeGame::miniMax(TicTacToeGame board, int player) {
move current, best;
int otherPlayer = (player == 1) ? 3 : 1;
if (board.hasWon()){
if(player == PLAYER1_INDEX){
best.score = 10;
return best;
} else if(player == AI_INDEX){
best.score = -10;
return best;
}
} else if(board.haveTied()){
best.score = 0;
return best;
}
if(player == AI_INDEX){
best.score = -9999999;
} else best.score = 9999999;
std::vector<int> possibleMoves = board.possibleMoves();
for (int i = 0; i < possibleMoves.size(); i++) {
board.setMarker(possibleMoves[i], player);
current = miniMax(board, otherPlayer);
current.index = possibleMoves[i];
if(player == AI_INDEX){
if(current.score > best.score) {
best = current;
}
} else
if(current.score < best.score){
best = current;
}
board.resetMarker(possibleMoves[i]);
}
std::cout << "best index: " << best.index << " best score: " << best.score << std::endl;
return best;
}
void TicTacToeGame::makeAIMove(TicTacToeGame board) {
int move = miniMax(board, getCurrentPlayer()).index;
setMarker(move, getCurrentPlayer());
std::cout << "\nThe AI has moved to " << move << std::endl;
}
std::vector<int> TicTacToeGame::possibleMoves() {
std::vector<int> possibleMoves;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if(board[i][j] != 'X' && board[i][j] != 'O'){
possibleMoves.push_back(3 * i +j);
}
}
}
return possibleMoves;
}
TicTacToeGame::TicTacToeGame() {
init();
}
// Create the board with indexes
void TicTacToeGame::init() {
currentPlayer = 2;
int k = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++, k++) {
board[i][j] = '0' + k;
}
}
}
// Prints the board int he format of a TicTacToe game
void TicTacToeGame::printBoard() {
std::cout << "\n";
for (int i = 0; i < 3; i++) {
if (i != 0) std::cout << "\n --------------------\n";
for (int j = 0; j < 3; j++) {
std::cout << "\t" << board[i][j];
if (j != 2) std::cout << "\t|";
}
}
}
// Handles the playing
void TicTacToeGame::play(TicTacToeGame game) {
std::string welcome = "\t\t*********************************************\n\t\t*\t\tWelcome to the TicTacToe game !\t\t*\n\t\t*********************************************\n\n\n";
int position = -1;
char multiplayer;
char playAgain;
std::cout << welcome;
while (true){
std::cout << "Do you want to play multiplayer ? (y/n): ";
std::cin >> multiplayer;
multiplayer = tolower(multiplayer);
// Checks if input is valid, asks for another input if not
while (std::cin.fail() || (multiplayer != 'y' && multiplayer != 'n')) {
std::cout << "Invalid entry ! Enter either y OR n: ";
std::cin.clear();
std::cin.ignore(256, '\n');
std::cin >> multiplayer;
multiplayer = tolower(multiplayer);
}
if (multiplayer == 'y') isMultiplayer = true;
else if (multiplayer == 'n') isMultiplayer = false;
break;
}
// Initializing players
std::cout << "Player 1, please type in your name: ";
std::cin >> player1_name;
// Checks if input is valid, asks for another input if not
while (std::cin.fail()) {
std::cout << "Invalid entry ! Re-enter your name: ";
std::cin.clear();
std::cin.ignore(256, '\n');
std::cin >> player1_name;
}
setPlayer1Name(player1_name);
std::cout << getPlayer1Name() << " will be X." << std::endl;
// Only initializes player 2 if it's a multiplayer game
if (isMultiplayer){
std::cout << "\nPlayer 2, please type in your name: ";
std::cin >> player2_name;
// Checks if input is valid, asks for another input if not
while (std::cin.fail()) {
std::cout << "Invalid entry ! Re-enter your name: ";
std::cin.clear();
std::cin.ignore(256, '\n');
std::cin >> player2_name;
}
setPlayer2Name(player2_name);
std::cout << getPlayer2Name() << " will be O.\n" << std::endl;
}
std::cout << "Starting game: \nINSTRUCTIONS: Select the number of the position where you want to play" << std::endl;
// Play loop
while (!hasWon()) {
printBoard();
// Alternate between players after evey move
switchCurrentPlayer();
std::cout << "\ncurrent player is " << currentPlayer << std::endl;
// Player's move
if (currentPlayer == PLAYER1_INDEX || currentPlayer == PLAYER2_INDEX){
while (true) {
std::cin >> position;
// Checks if input is an integer, asks for another input if not
while (std::cin.fail() || position < 0 || position > 8) {
std::cout << "Invalid entry ! Enter a number between 0 and 8 inclusive: ";
std::cin.clear();
std::cin.ignore(256, '\n');
std::cin >> position;
}
// Check if there's an X or O in that position already, if yes - ask for another position to if so. If no - writes X/O
if (checkMarker(getRow(position), getColumn(position))) {
setMarker(position, getCurrentPlayer());
break;
} else {
std::cout
<< "There's already an X/O in that position. Try place it in an empty spot.\nEnter a new position: ";
}
}
}
// AI's move
else if (currentPlayer == AI_INDEX){
makeAIMove(game);
}
moveCount++;
// Checks for a winner or a tie after every move
if (hasWon() || haveTied()) {
if (hasWon()) std::cout << winMessage() << std::endl;
else if(haveTied()) std::cout << "The game is a tie !" << std::endl;
std::cout << "\n\nDo you want to play again ? Enter y OR n: ";
std::cin >> playAgain;
playAgain = tolower(playAgain); // converts to lowercase
// If there's a winner ask if user wants to play another game, stops application if not
while (true) {
if (playAgain != 'y' && playAgain != 'n') {
std::cout << playAgain << std::endl;
std::cout << "Invalid expression ! Enter either y OR n: ";
std::cin >> playAgain;
playAgain = tolower(playAgain); // converts to lowercase
} else if (playAgain == 'y' || playAgain == 'n') break;
}
if (playAgain == 'y') {
std::cout << "Generating a new board " << std::endl;
init();
moveCount = 0;
} else if (playAgain == 'n') {
std::cout << "\nThank you for playing the TicTacToe game !\nExiting the game.";
break;
}
}
}
}
std::string TicTacToeGame::winMessage() {
if (getCurrentPlayer() == 1) { return "\n\n" + getPlayer1Name() + " has won !"; }
else if (getCurrentPlayer() == 2) return "\n\n" + getPlayer2Name() + "has won !";
else return "\n\nThe AI has won !";
}
// Checks for winning conditions
bool TicTacToeGame::hasWon() const {
for (int i = 0; i < 3; ++i) {
// Checking horizontals
if (getMarker(0, i) == getMarker(1, i) && getMarker(1, i) == getMarker(2, i)) {
//cout << "horizontal alignment";
return true;
}
// Chekcing verticals
if (getMarker(i, 0) == getMarker(i, 1) && getMarker(i, 1) == getMarker(i, 2)) {
//cout << "vertical alignment";
return true;
}
}
// Checking diagonals
if (getMarker(0, 0) == getMarker(1, 1) && getMarker(1, 1) == getMarker(2, 2)) return true;
if (getMarker(0, 2) == getMarker(1, 1) && getMarker(1, 1) == getMarker(2, 0)) return true;
// If no alignment
return false;
}
void TicTacToeGame::setPlayer1Name(std::string name) {
player1_name = name;
}
void TicTacToeGame::setPlayer2Name(std::string name) {
player2_name = name;
}
std::string TicTacToeGame::getPlayer1Name() const {
return player1_name;
}
std::string TicTacToeGame::getPlayer2Name() const {
return player2_name;
}
int TicTacToeGame::getCurrentPlayer() const {
return currentPlayer;
}
int TicTacToeGame::getRow(int row) const{
return row / 3;
}
int TicTacToeGame::getColumn(int column) const {
return column % 3;
}
bool TicTacToeGame::checkMarker(int row, int column) {
if (getMarker(row, column) == 'X' || getMarker(row, column) == 'O') return false;
return true;
}
char TicTacToeGame::getMarker(int row, int column) const {
return board[row][column];
}
void TicTacToeGame::setMarker(int position, int player) {
board[getRow(position)][getColumn(position)] = player == 1 ? 'X' : 'O';
}
/* Switches the play either from:
* - PLAYER1 to PLAYER2
* - PLAYER 2 to PLAYER1
* - AI to PLAYER1
* - PLAYER1 to AI
*/
void TicTacToeGame::switchCurrentPlayer() {
if (currentPlayer == PLAYER1_INDEX && !isMultiplayer){
currentPlayer = AI_INDEX;
std::cout << "\n\nIt's the AI's turn now" << std::endl;
} else if (currentPlayer == PLAYER1_INDEX) {
currentPlayer = PLAYER2_INDEX;
std::cout << "\n\nIt's " << getPlayer2Name() << "'s turn, select the position you want to move to:";
} else if (currentPlayer == PLAYER2_INDEX || currentPlayer == AI_INDEX) {
currentPlayer = PLAYER1_INDEX;
std::cout << "\n\nIt's " << getPlayer1Name() << "'s turn, select the position you want to move to:";
}
}
bool TicTacToeGame::haveTied() const {
if (moveCount == 9) return true;
return false;
}
void TicTacToeGame::resetMarker(int position) {
board[getRow(position)][getColumn(position)] = (char) position;
}
main.cpp
#include "TicTacToeGame.h"
int main() {
TicTacToeGame game;
game.play(game);
return 0;
}
This line:
std::cout << "best index: " << best.index << " best score: " << best.score << std::endl;
best.index is uninitialized when this line is printed. That is, you never set best.index to a value.
Further, you are passing an instance of TicTacBoard by value as a parameter to another instance of methods on the same class. Some of your code operates on the board parameter. Other parts work implicitly on this. You probably want to eliminate the passing around of board by value.
Change your code such that it's invoked like this in main.
TicTacToeGame game;
game.play();
And remove all the places where you pass board as a parameter.

C++ Subset array finder looping with comma at ending?

Here is my code
#include "iostream"
using namespace std;
void choice();
void Start(){
system("cls");
char subset[100];
int y,x;
cout << "Enter a Set"<<endl;
int pass = 0;
while (pass < 1){
y = 0;
x = 0;
cin >> subset;
while(y < 100){
if (subset[x+1] == '}') { cout<<"Invalid Set"<<endl<<"Enter a Set"<<endl; break; }
if (subset[x] == '}'&& subset[0] == '{') { cout << "Set Accepted"<<endl; pass = 1; break;}
x = x+2;
if (y == 99) {cout <<"Invalid Set"<<endl<<"Enter a Set"<<endl; }
y++;
}
}
int nofsubset = x / 2;
int b = 1;
char arr[99];
int n = nofsubset;
while(nofsubset!= 0) {
for(int l=0; l<n; l++){
//cin >> arr[l];
arr[l] = subset[b];
b = b + 2;
}
for (int i=0; i<(1<<n); i++){
cout << "{";
for(int j=0; j<n; j++) {
if(i & (1 <<j)) {
cout << arr[j];
}
}
cout <<"}"<<endl;
}
nofsubset = 0;
}
system("pause");
choice();
}
void choice(){
system("cls");
cout <<"**************************"<<endl;
cout <<"* *"<<endl;
cout <<"* 1 - Generate Subsets *"<<endl;
cout <<"* 2 - Exit *"<<endl;
cout <<"* *"<<endl;
cout <<"**************************"<<endl;
int choice;
cin >> choice;
if(choice == 1){ Start();}
else{ return ;}
}
int main() {
choice();
}
this code would allow to find subset of set for example i entered {1,2,3} and it will generate
{}
{1}
{2}
{12}
{3}
{13}
{23}
{123}
what my professor want is to out put it on format with comma like this
{}
{1}
{2}
{1,2}
{3}
{1,3}
{2,3}
{1,2,3}
can anyone please help me edit my code i cant seem to just put "," on the loop array because itl produce {1,2,3,}
thanks in advance!
cout << "{";
bool first = true;
for(int j=0; j<n; j++) {
if(i & (1 <<j)) {
if (!first) cout << ","; // <<< try this
first = false;
cout << arr[j];
}
}
cout <<"}"<<endl;

C++ a function call is not called again after the loop iterates

Hey so I am relatively a beginner at programming. I am trying to create a very simple minesweeper game over a 2D array, the issue I am running into is after the player steps on a mine (game over) they are given the option to play again. After this the set difficulty function is supposed to be called a second time (since it is within the loop) and a new minefield is to be generate. Unfortunately none of that is happening and the program skips that process.
Here is my code:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int choose_difficulty(int x);
int generator();
int main()
{
//create initial variables
string Ans;
int Rounds;
int NewPosition_x = 0;
int NewPosition_y = 0;
//ask user if he wants to run the program and expect input
cout << "Would you like to play a game? Y/N" << endl;
cin >> Ans;
//based on user input the program will run or not
if (Ans == "Y" || "y") {
while (Ans == "Y" || "y")
{
//Create position variables to be checked
int Position_x;
int Position_y;
//ask user how many rounds in the game they want
cout << "How many chances do you want to give yourself?" << endl;
cin >> Rounds;
//Generate minefield could not be done as separate function since you cannot output an array
int a = choose_difficulty(a);
int mines;
int n,m;
srand (time (0));
if(a == 0) {
mines = 3;
n = 4;
m = n;
}
else if (a == 1){
mines = 5;
n = 4;
m = n;
}
else if (a == 2){
mines = 7;
n = 4;
m = n;
}
int minefield[n][m] = { };
int g, h;
for (int num = 0; num < mines; num++) {
g = rand()%n;
h = rand()%n;
minefield[g][h] = 1;
}
for (int x = 0; x < Rounds; x++)
{
//Begin Game
cout << "Where are you at to avoid the mines? (Enter a 2 numbers 0 through 3)" << endl;
cin >> NewPosition_x >> NewPosition_y;
//check if the player has entered a new position
while (NewPosition_x == Position_x && NewPosition_y == Position_y) {
cout << "You have to move somewhere, put a valid location" << endl;
cin >> NewPosition_x >> NewPosition_y;
}
//check to see if that position is valid
while ((NewPosition_x < 0 || NewPosition_x > 3) || (NewPosition_y < 0 || NewPosition_y > 3)) {
cout << "I'm sorry, but that place doesn't exist. Try somewhere else" << endl;
cin >> NewPosition_x >> NewPosition_y;
}
//Assign Player Position and check position vs mines
Position_x = NewPosition_x;
Position_y = NewPosition_y;
if (minefield[Position_y][Position_x] == 1) {
cout << "You stepped on a mine, Game Over" << endl;
cout << "You minefield was this:" << endl;
for (int i=0; i < n; i++){
for (int j=0; j < n; j++){
cout << minefield[i][j] << "\t";
}
cout << endl;
}
cout << "Would you like to play again? Y/N" << endl;
cin >> Ans;
if (Ans == "n" || Ans == "N"){
return 0;
}
}
else if ((minefield[Position_x + 1][Position_y] == 1) || (minefield[Position_x - 1][Position_y] == 1) || (minefield[Position_x][Position_y + 1] == 1) || (minefield[Position_x][Position_y - 1] == 1)) {
cout << "You're hot right now, you better watch your step. Continue to the next round" << endl;
}
else {
cout << "You're safe. Continue to the next round" << endl;
}
}
}
}
return 0;
}
int choose_difficulty(int a)
{
do{
string difficulty;
//Difficulty Selection
cout << "Choose the game difficulty: Easy, Medium, Hard" << endl;
cin >> difficulty;
if (difficulty == "easy" || difficulty == "Easy"){
a = 0;
}
else if (difficulty == "medium" || difficulty == "Medium"){
a = 1;
}
else if (difficulty == "hard" || difficulty == "Hard"){
a = 2;
}
else {
cout << "Invalid input";
a = 3;
}
}while (a == 3);
return a;
}
You should be careful on this kind of error:
//based on user input the program will run or not
if (Ans == "Y" || "y") {
while (Ans == "Y" || "y")
{
This, above, will always be true being "y" different from 0 (false).
Instead you need to check that Ans is either equal to "Y" or "y" in this way:
//based on user input the program will run or not
if (Ans == "Y" || Ans == "y") {
while (Ans == "Y" || Ans == "y")
{
Or use, as suggested in the comments, std::toupper()
UPDATE
It seems you have a problem on your buffer you should use cin.ignore() in order to clean it;

C++ Programming Tic Tac Toe AI attempt

I've tried to look into the already existing codes for Tic Tac Toe, and found out there's an algorithm called MiniMax, although I've understood how it works, I can't seem to make it work using 5*5 table for Tic Tac Toe.
I've an idea of how I'll do it, but I can't seem to find an approach for it.
I'm trying to make a check for every 4 moves in 1 col/row/diagonals so that there's a win there, or there's a block if it's the other player. but I can't seem to find how I can do that, I've been working on it for the past 6 hours.
#include <iostream>
#include <cstdlib>
#include <time.h>
char arr[5][5];
char player1 = 'X';
char player2 = 'O';
char player = player1;
using namespace std;
void display() {
cout << " 1 " << "2 " << "3 "<<"4 "<<"5 " << endl;
cout << " ----------------" << endl;
for (int row = 0; row < 5; row++) {
cout << row + 1 << " | ";
for (int col = 0; col < 5; col++) {
cout << arr[row][col] << " ";
}
cout << endl;
}
}
void new_turn();
int firstEmptyRow(int c){
int i;
for(i=0;i<5;i++){
if(arr[i][c])
return i;
}
}
int firstEmptyCol(int r){
int i;
for(i=0;i<5;i++){
if(arr[r][i])
return i;
}
}
bool canWin(int mat[5][5]){
int row,col;
int countSteps;
// FOR VERTICAL |
//trying to find a count of 4 moves in 1 row, so It can be won.
for(row=0;row<5;row++){
countSteps=0;
for(col=0;col<5;col++){
if( (arr[row][col] == arr[row+1][col])
&&(arr[row][col] ==player2)){
countSteps++;
}
}
if(countSteps==4){ cout << "MOVE IS WIN-ABLE" << endl; return true;}
}
return false;
}
int computer_move(){
char temp;
int test[5][5], tempo[5][5];
int row, col;
for(row=0;row<5;row++){
for(col=0;col<5;col++){
test[row][col] = arr[row][col];
tempo[row][col] = arr[row][col];
}
}
for(row=0;row<5;row++){
for(col=0;col<5;col++){
if(arr[row][col] == '-'){
temp = arr[row][col];
if(canWin(test)){ // an attempt to test the move
}
}
}
}
}
void player_move() {
if(player==player1){
int his_moveRow, his_moveCol;
cout << "please enter your move row player " << player << endl;
cin >> his_moveRow;
cout << "please enter your move col player " << player << endl;
cin >> his_moveCol;
if (his_moveRow < 0 || his_moveRow > 5 || his_moveCol < 0 || his_moveCol > 5) {
cout << "please enter a number from 1 to 5 player " << player << endl;
player_move();
}
--his_moveRow;
--his_moveCol;
if (arr[his_moveRow][his_moveCol] == '-') {
arr[his_moveRow][his_moveCol] = player;
} else {
cout << "please try again player " << player << endl;
player_move();
}
}else{
//computer move!!
cout <<"Computer Move!"<< endl;
computer_move();
}
if (player == player1) {
player = player2;
} else {
player = player1;
}
new_turn();
}
bool check_win();
void new_turn() {
display();
if (check_win() == true) {
cout << "congratulation player " << player << " you won!" << endl;
return;
} else {
int row, col, count = 0;
for (row = 0; row < 5; row++) {
for (col = 0; col < 5; col++) {
if (arr[row][col] != '-') count++;
}
}
if (count == 25) {
cout << "No one won. That's a draw." << endl;
return;
} else {
cout << "next turn" << endl;
player_move();
}
}
}
bool check_win() {
//Vertical |
int row, col;
for (row = 0; row < 5; row++) {
for (col = 0; col < 5; col++) {
if ((arr[row][col] == arr[row + 1][col] && arr[row + 1][col] == arr[row + 2][col])
&&(arr[row+2][col] == arr[row + 3][col] && arr[row + 3][col] == arr[row + 4][col])
&& arr[row][col] != '-') {
cout << "player won" << endl;
player = arr[row][col];
return true;
}
}
}
//Horizontal -
for (row = 0; row < 5; row++) {
for (col = 0; col < 5; col++) {
if ((arr[row][col] == arr[row][col + 1] && arr[row][col + 1] == arr[row][col + 2])
&&(arr[row][col+2] == arr[row][col + 3] && arr[row][col + 3] == arr[row][col + 4])
&& arr[row][col] != '-') {
cout << "player won" << endl;
player = arr[row][col];
return true;
}
}
}
//Diagonal "\"
row=0,col=0;
if((arr[row][col] == arr[row+1][col+1] && arr[row+1][col+1] == arr[row+2][col+2]
&& arr[row+2][col+2] == arr[row+3][col+3])
&&(arr[row+3][col+3] == arr[row+4][col+4]) && arr[row][col] != '-'){
cout << "player won" << endl;
player = arr[row][col];
return true;
}
// Diagonal " / "
for (row = 4; row >= 0; row--) {
for (col = 0; col < 5; col++) {
if ((arr[row][col] == arr[row - 1][col + 1] && arr[row - 1][col + 1] == arr[row - 2][col + 2]
&& arr[row - 2][col + 2] == arr[row - 3][col + 3]
&& arr[row - 3][col + 3] == arr[row - 4][col + 4]) && arr[row][col] != '-') {
cout << "player won" << endl;
player = arr[row][col];
return true;
}
}
}
return false;
}
void game_start() {
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
arr[row][col] = '-';
}
}
display();
player_move();
}
int main() {
srand(time(NULL));
game_start();
return 0;
}
I once did something similar, though not using that MiniMax algorithm. I used a comic "guide" from xkcd that tells about optimal tic tac toe moves.
If your program follows this, you can never lose, only win or tie.
https://xkcd.com/832/

Taking "exit" as user input in C++

I'm currently trying to write code that takes user input as strings, and then convert them to integers if I need to. If the user decides to enter exit then the program should move on to calling a function. Here is what I have so far:
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
if (stoi(user_input) < 0 || stoi(user_input) > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
cin >> user_input;
}
else if (user_input == "exit"){
printArray(string_array, 10);
}
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
However, as I'm testing the program, the console is aborting the program if I enter exit. Is there a way for me to enter exit and then the program calls printArray?
I think this changes in your code will solve the problem. Please, try with this code:
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
if (user_input == "exit"){
printArray(string_array, 10);
}
else if (stoi(user_input) < 0 || stoi(user_input) > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
cin >> user_input;
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
}
}
Hope this helps
stoi doesn't accept non-numbers. Try this:
#include <iostream>
using namespace std;
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
//cout << "You have printed " << user_input << endl;
bool isNumber = true;
for(string::const_iterator k = user_input.begin(); k != user_input.end(); ++k) {
if (isdigit(*k) == false) {
isNumber = false;
break;
}
}
if (isNumber) {
int number = stoi(user_input);
if (number < 0 || number > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
continue;
} else {
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
} else if (user_input == "exit"){
printArray(string_array, 10);
break;
} else {
// Not a number and not "exit"; do nothing?
}
}
}
int main() {
a_func();
return 0;
}