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/
Related
So everything in my code works so far, but I don't know why the checkWinner function doesn't work. In my Bool checkWinner function, I used bool. When I call the function I'm not sure where to put it as well.
What I tried: one place where I have tried was in my for loop in the main function. Ex:
checkWinner(board, gwinner)
However it doesn't work, the game keeps on playing when someone even has three X's or O's.
Possible problems I see: I'm not sure what's wrong, could it be my checkwinner function, or could it be my playerChoice function?
The question is why isn't a winner being picked? Thank you for the help.
#include <iostream>
#include <string>
using namespace std;
const int ROWS = 3; // For the rows
const int COLS = 3; // For the number of columns;
void showBoard(const char[][COLS], int); // Shows the board
void playerChoice(char[][COLS], char); // shows the player choice
bool checkwinner(const char[][COLS], string);
int main()
{
char board[ROWS][COLS] = { { '*', '*', '*' }, { '*', '*', '*' }, { '*', '*', '*' } };
string gwinner = " ";
showBoard(board, 3); // displays the board
for (int i = 0; i < 4; i++) {
playerChoice(board, 'X');
showBoard(board, 3);
playerChoice(board, 'O');
showBoard(board, 3);
}
cout << "The winner is: " << gwinner;
}
void showBoard(const char arr[][COLS], int SIZE)
{
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++)
cout << '|' << arr[row][col];
cout << '|' << endl;
}
}
void playerChoice(char arr[][COLS], char name)
{
int row, columns;
char board[ROWS][COLS] = { { '*', '*', '*' }, { '*', '*', '*' }, { '*', '*', '*' } };
cout << "What row would you like?\n";
cout << "Row: ";
cin >> row;
while (row < 1 || row > 3) {
cout << "Error please pick a row between 1 and 3.\n";
cout << "Row: ";
cin >> row;
cout << endl;
}
cout << "What column would you like?\n";
cout << "Column: ";
cin >> columns;
while (columns < 1 || columns > 3) {
cout << "Error,please pick a column between 1 and 3.\n";
cout << "Column: ";
cin >> columns;
cout << endl;
}
if (arr[row - 1][columns - 1] == '*') {
arr[row - 1][columns - 1] = name;
}
else {
cout << "This space is occupied.\n";
cout << "Please select again\n";
}
}
bool checkwinner(const char arr[][COLS], string gwinner)
{
bool winner = false;
if ((arr[0][0] == arr[0][1]) && (arr[0][1] == arr[0][2])) // checks row
{
winner = true;
}
else if ((arr[1][0] == arr[1][1]) && (arr[1][1] == arr[1][2])) // checks row
{
winner = true;
}
else if ((arr[2][0] == arr[2][1]) && (arr[2][1] == arr[2][2])) // checks row
{
winner = true;
}
else if ((arr[0][0] == arr[1][0]) && (arr[1][0] == arr[2][0])) // checks columns
{
winner = true;
}
else if ((arr[0][1] == arr[1][1]) && (arr[1][1] == arr[2][1])) // checks columns
{
winner = true;
}
else if ((arr[0][2] == arr[1][2]) && (arr[1][2] == arr[2][2])) // checks columns
{
winner = true;
}
else if ((arr[0][0] == arr[1][1]) && (arr[1][1] == arr[2][2])) // checks diagonal
{
winner = true;
}
else if ((arr[2][0] == arr[1][1]) && (arr[1][1] == arr[0][2])) // checks diagonal
{
winner = true;
}
else {
gwinner = "It's a tie! ";
winner = false;
}
return winner; // returns the winner
}
Hey guys I want to make a calculator for matrixes but I have problems.
first, when I want to multiply them it will work when columns and rows are equal in the matrixes but when it's different like n1=5 m1=2 n2=2 m2=6 it goes wrong and have some bugs
and the bigger problem is for calculating the determinate I have no idea what should I do
thanks for answering.
this the code
#include <iostream>
using namespace std;
int main() {
int n1, m1, n2, m2;
int counter = 0;
int ask;
bool matrixCheck;
int determinant = 0;
cout << "pls enter N1" << endl;
cin >> n1;
while (n1 > 100) {
cout << "N most be lower than 100";
cin >> n1;
}
cout << "pls enter M1" << endl;
cin >> m1;
while (m1 > 100) {
cout << "M most be lower than 100";
cin >> m1;
}
cout << "pls enter N2" << endl;
cin >> n2;
while (n2 > 100) {
cout << "N most be lower than 100";
cin >> n2;
}
cout << "pls enter M2" << endl;
cin >> m2;
while (m2 > 100) {
cout << "M most be lower than 100";
cin >> m2;
}
int matrixA[n1][m1];
int matrixB[n2][m2];
cout << "ENTER MATRIX A" << endl;
for (int i = 0; i <= n1 - 1; i++) {
cout << " ";
cout << counter + 1 << "," << i + 1 << "= ";
cin >> matrixA[counter][i];
cout << " ";
if (i == n1 - 1) {
cout << endl;
counter++;
i = -1;
}
if (counter == m1) {
break;
}
}
counter = 0;
cout << "This is A" << endl;
for (int j = 0; j <= n1 - 1; j++) {
cout << matrixA[counter][j] << " ";;
if (j == n1 - 1) {
cout << endl;
counter++;
j = -1;
}
if (counter == m1) {
break;
}
}
counter = 0;
cout << "ENTER MATRIX B" << endl;
for (int k = 0; k <= n2 - 1; k++) {
cout << " ";
cout << counter + 1 << "," << k + 1 << "= ";
cin >> matrixB[counter][k];
cout << " ";
if (k == n2 - 1) {
cout << endl;
counter++;
k = -1;
}
if (counter == m2) {
break;
}
}
counter = 0;
cout << "This is B" << endl;
for (int q = 0; 1 <= n2 - 1; q++) {
cout << matrixB[counter][q] << " ";;
if (q == n2 - 1) {
cout << endl;
counter++;
q = -1;
}
if (counter == m2) {
break;
}
}
cout << "Choose an operation" << endl
<< "1-(+) 2-(-) 3-(A * B) 4-(A / B) 5-(A --> B) 6-(B --> A) 7-(a * A) 8-(|A|) 9-(|B|)" << endl;
if (n1 != n2 || m1 != m2) {
cout
<< "We have to note that you can't use operaroin number 1, 2, 5 and 6 because the length of the matrixs are different"
<< endl;
matrixCheck = false;
} else if (n1 == n2 && m1 == m2) {
matrixCheck = true;
}
cin >> ask;
while (ask == 1 || ask == 2 || ask == 5 || ask == 6) {
if (matrixCheck) {
break;
}
cout
<< "We have to note that you can't use operaroin number 1, 2, 5 and 6 because the length of the matrixs are different"
<< endl;
cin >> ask;
}
if (ask == 1 && matrixCheck) {
counter = 0;
for (int n = 0; n <= n1 - 1; n++) {
matrixA[counter][n] = matrixA[counter][n] + matrixB[counter][n];
if (n + 1 == n1) {
n = -1;
if (counter + 1 == m1) {
break;
}
counter++;
}
}
counter = 0;
cout << "This is A" << endl;
for (int j = 0; j <= n1 - 1; j++) {
cout << matrixA[j][counter] << " ";;
if (j == n1 - 1) {
cout << endl;
counter++;
j = -1;
}
if (counter == m1) {
break;
}
}
}
if (ask == 2 && matrixCheck) {
counter = 0;
for (int n = 0; n <= n1 - 1; n++) {
matrixA[counter][n] = matrixA[counter][n] - matrixB[counter][n];
if (n + 1 == n1) {
n = -1;
if (counter + 1 == m1) {
break;
}
counter++;
}
}
counter = 0;
cout << "This is A" << endl;
for (int j = 0; j <= n1 - 1; j++) {
cout << matrixA[j][counter] << " ";;
if (j == n1 - 1) {
cout << endl;
counter++;
j = -1;
}
if (counter == m1) {
break;
}
}
}
if (ask == 3) {
int matrixResult[n1][m1];
int sum = 0;
// Multiplying two matrices...
for (int i = 0; i < n1; i++) {
for (int j = 0; j < m2; j++) {
sum = 0;
for (int k = 0; k < m1; k++)
sum = sum + (matrixA[i][k] * matrixB[k][j]);
matrixResult[i][j] = sum;
}
}
cout << "\nMultiplication Result:\n";
counter = 0;
for (int j = 0; j <= n1 - 1; j++) {
cout << matrixResult[j][counter] << " ";;
if (j == n1 - 1) {
cout << endl;
counter++;
j = -1;
}
if (counter == m2) {
break;
}
}
}
}
and this the result
pls enter N1
3
pls enter M1
2
pls enter N2
2
pls enter M2
3
ENTER MATRIX A
1,1=3
1,2=3
1,3=3
2,1=3
2,2=3
2,3=3
This is A
3 3 3
3 3 3
ENTER MATRIX B
1,1=3
1,2=3
2,1=3
2,2=3
3,1=3
3,2=3
This is B
3 3
3 3
3 3
Choose an operation
1-(+) 2-(-) 3-(A * B) 4-(A / B) 5-(A --> B) 6-(B --> A) 7-(a * A) 8-(|A|) 9-(|B|)
We have to note that you can't use operaroin number 1, 2, 5 and 6 because the length of the matrixs are different
3
Multiplication Result:
18 18 12600660
18 18 12600660
18 12600660 364487398
Process finished with exit code 0
Size of resulting matrix is n1 * m2, not n1*m1.
The function player_attack() changes the elements of the multi-dimensional array pc_board but when i reprint it in main, the array prints unchanged.
I removed all unnecessary code.
I tried to pass is at as a parameter to the function but i got an error for using a multidimensional array in the parameter.
$
bool game_won = false;
string board[5][5];
string pc_board[5][5];
void initialize_player_board() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
board[i][j] = "-";
}
}
}
void print_map() {
for (int i = 0; i < 5; i++) {
cout << setw(5);
cout << i << setw(5);
for (int j = 0; j < 5; j++) {
cout << board[i][j] << setw(5);
}
cout << setw(10);
for (int j = 0; j < 5; j++) {
cout << pc_board[i][j] << setw(5);
}
cout << endl;
}
}
void pc_add_battleship() {
int x = 0;
int y = 0;
int choice_generator = 0;
char choice;
x = rand() % 4 + 1;
y = rand() % 4 + 1;
choice_generator = rand() % 2;
if (choice_generator == 0) {
choice = 'h';
}
else {
choice = 'v';
}
if (choice == 'h') {
pc_board[y - 1][x] = 'O';
pc_board[y][x] = 'O';
pc_board[y + 1][x] = 'O';
}
if (choice == 'v') {
pc_board[y][x - 1] = 'O';
pc_board[y][x] = 'O';
pc_board[y][x + 1] = 'O';
}
}
void player_attack() {
int x = 0;
int y = 0;
cout << "Choose an x coordinate to attack: " << endl;
cin >> x;
cout << "Choose a y coordinate to attack: " << endl;
cin >> y;
if (pc_board[y][x] == "O") {
cout << "HIT!" << endl;
pc_board[y][x] == "H";
}
else {
cout << "Miss." << endl;
pc_board[y][x] == "M";
}
}
int main()
{
srand(time(0));
initialize_player_board();
initialize_pc_board();
cout << "Welcome to the battleship game." << endl;
print_map();
Add_battleship();
pc_add_battleship();
while (!game_won) {
print_map();
player_attack();
}
return 0;
}
$
I expected for the multidimensional array to change its elements due to the function
In your function player_attack you use wrong operator:
if (pc_board[y][x] == "O") {
cout << "HIT!" << endl;
pc_board[y][x] == "H"; // here
}
else {
cout << "Miss." << endl;
pc_board[y][x] == "M"; // and here
}
instead of == that is a comparison operator you should use = that is the assignment operator.
Using operator == in this context is still valid C++ syntax, which produces a boolean value, however it does not modify the arguments (which are left and right side of comparison), which is probably what you want to do in most cases. Enabling compiler flags like -Wall or Wextra along with Werror helps to avoid this kind of bugs.
this is my first time asking a question on this forum so here it goes. I am creating a tic-tac-toe game for practice and am using enumerators and recursion because I have never really done enumeration and could always get some recursion practice in. Well anyway I just finished coding for the player2 to take a random move and after about 3 turns it gives a segmentation fault and I cannot figure out why... I hope you guys can figure it out and thank you!
#include <iostream>
#include <string>
#include <cstdlib>
const int size = 3;
enum play {none,X,O};
void NPC(play (&board)[size][size],play player2) {
srand(time(NULL));
int tempx = rand() % 3;
int tempy = rand() % 3;
if(board[tempx][tempy] == none)
board[tempx][tempy] = player2;
else
NPC(board,player2);
}
void getBoardState(play (&board)[size][size],int y,int x) {
if(board[x][y] == none) std::cout << " ";
else if(board[x][y] == X) std::cout << "X";
else std::cout << "O";
}
void printboard(play (&board)[size][size]){
int length = 4 * size - 1;
for(int i = 1; i <= length; i++) {
for(int j = 1; j <= length; j++) {
if(i % 4 == 0 && j % 4 == 0) std::cout << "+";
else if(i % 4 == 0) std::cout << "-";
else if(j % 4 == 0) std::cout << "|";
else if(i % 2 == 0 && j % 2 == 0) getBoardState(board,(i - 2)/4,(j - 2)/4);
else std::cout << " ";
}
std::cout << std::endl;
}
}
int main() {
play player = O, player2 = X;
bool over = false;
play board[size][size];
for(int i = 0; i < size; i++) {
for(int j = 0; j < size; j++) {
board[i][j] = none;
}
}
std::string player1 = "";
std::cout << "What would You like to be? An X or an O?" << std::endl;
while(((player1 != "X") + (player1 != "O")) == 2) {
std::cin >> player1;
if(((player1 != "X") + (player1 != "O")) == 2)
std::cout << "Invalid entry! Please enter X or an 0!" << std::endl;
}
if(player1 == "X") {
player2 = O;
player = X;}
int tempx,tempy;
while(!over) {
std::cout << "Please enter an x and then a y (1 to " << size << ")" << std::endl;
std::cin >> tempx;
std::cin >> tempy;
while(tempx > size || tempy > size || board[tempx-1][tempy-1] != none) {
std::cout << "Invalid entry! Try again!" << std::endl;
std::cin >> tempx;
std::cin >> tempy;
}
board[tempx-1][tempy-1] = player;
NPC(board,player2);
printboard(board);
}
return 0;
}
You're running out of stack space in your recursion because you call srand(time(NULL)) every time. The random number generator should only be seeded once, in main, and not in NPC. time(NULL) returns a number of seconds, so it changes infrequently (compared to how fast your recursive function calls will occur) which will consume all available stack space.
My code is below. I have tried all different options. I am still learning C++ through classes but have reached an impasse. Xcode says error are in the lines there are three straight * marks. Ex: ***code* Any advice would be great and looking for ways to understand arrays better.
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
int board [7] [7];
void initBoard (int array1[7][7]) {
srand(time(0));
string position[7][7];
int moves = rand() % 8 + 5;
int r = 0;
int c = 0;
for (c = 0; c < 7; c++) {
if (c == 0 || c == 6) {
for (r = 0; r < 7; r++) {
position[r][c] = " ";
}
}
else {
for (r = 0; r < 7; r++) {
if (r == 0 || r == 6) {
position[r][c] = " ";
}
else {
position[r][c] = "_ ";
}
}
}
}
***void plantBombs (int array2[7][7]) {***
r = 0;
c = 0;
int k = (rand() % 5) + 1;
int d = ((rand() % 111) % 5) + 1;
int numBombs = rand() % 4 + 3;
int bombR[numBombs];
int bombC[numBombs];
int i = 0;
while (i < numBombs){
bombR[i] = (rand() % 71) % 5 + 1;
bombC[i] = (rand() % 123) % 5 + 1;
while (bombR[i] == k && bombC[i] == d) {
bombR[i] = (rand() % 97) % 5 + 1;
bombC[i] = (rand() % 79) % 5 + 1;
}
while ((i > 0) && (bombR[i-1] == bombR[i]) && (bombC[i-1] == bombC[i])){
bombR[i] = (rand() % 213) % 5 + 1;
bombC[i] = (rand() % 857) % 5 + 1;
}
position[bombR[i]][bombC[i]] = "* ";
i = i + 1;
}
}
***void placeYou (int array2[7][7]){***
position[k][d] = "U ";
}
***void movePlayer (int arrary3[7][7]){***
while (moves != 0) {
cout << "SURVIVE " << moves << " MORE MOVES!" << endl;
for (c = 0; c < 7; c++) {
for (r = 0; r < 7; r++) {
cout << position[r][c];
}
cout << endl;
}
cout << "Enter direction (N/S/E/W): ";
string direction;
cin >> direction;
//if (direction == "N")
if (direction == "N"){
if (position[k][d-1] == " "){
cout << "You fell off the board" << endl;
cout << "***YOU LOSE***" << endl;
break;
}
else if (position[k][d-1] == "* "){
cout << "BANG! YOUR DEAD!" << endl;
cout << "***YOU LOSE!***";
break;
}
else {
position[k][d] = "* ";
position[k][d-1] = "U ";
d = d - 1;
}
}
if (direction == "E"){
if (position[k+1][d] == " "){
cout << "You fell off the board" << endl;
cout << "***YOU LOSE***" << endl;
break;
}
else if (position[k+1][d] == "* "){
cout << "BANG! YOUR DEAD!" << endl;
cout << "***YOU LOSE!***";
break;
}
else {
position[k][d] = "* ";
position[k+1][d] = "U ";
k = k + 1;
}
}
if (direction == "S"){
if (position[k][d+1] == " ") {
cout << "You fell off the board" << endl;
cout << "***YOU LOSE***" << endl;
break;
}
else if (position[k][d+1] == "* "){
cout << "BANG! YOUR DEAD!" << endl;
cout << "***YOU LOSE!***";
break;
}
else {
position[k][d] = "* ";
position[k][d+1] = "U ";
d = d + 1;
}
}
if (direction == "W"){
if (position[k-1][d] == " "){
cout << "You fell off the board" << endl;
cout << "***YOU LOSE***" << endl;
break;
}
else if (position[k-1][d] == "* "){
cout << "BANG! YOUR DEAD!" << endl;
cout << "***YOU LOSE!***";
break;
}
else {
position[k][d] = "* ";
position[k-1][d] = "U ";
k = k - 1;
}
moves = moves - 1;
}
if (moves == 0){
cout << "***YOU WIN***";
}
else {
cout << "";
}
}
}
}
int main()
{
initBoard(board);
***plantBombs(board);
placeYou(board);
movePlayer(board);***
return 0;
}