The title kind of says it all. I'm not sure exactly why the Tic Tac Toe program is not detecting a tie. I've attached the main function, additional functions, etc.. I'm not sure what im doing wrong. Any help is greatly appreciated.
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
string displayBoard(string board[9]); // displays tic tac toe board
bool isGameOver(string board[9]); // checks if game is over
void displayGameWelcome(); // displays welcome message
int main()
{
string board[9]; // tic tac toe, top row 0 thru 2, middle row 3 thru 5, bottom row 6 thru 8
int position = 0; // player's position
bool gameOver = false; // flag variable to mark end of the game
bool validMove = false; // determines if move is valid or not
displayGameWelcome();
// initializing board with blank spaces
for (int i = 0; i < 9; i++)
{
board[i] = " ";
}
while (!gameOver)
{
// player #1's turn **************************
validMove = false;
while (!validMove)
{
cout << "Enter your position: ";
cin >> position;
if (position >= 0 && position <= 8 && board[position] == " ")
{
validMove = true;
board[position] = "x"; // placing x in desired board location
}
else
{
cout << "That position is already occupied." << endl;
cout << displayBoard(board) << endl;
}
}
cout << displayBoard(board) << endl;
if (isGameOver(board))
{
gameOver = true;
}
// player #2's turn **********************************
validMove = false;
while (!validMove)
{
cout << "Enter your position: ";
cin >> position;
if (position >= 0 && position <= 8 && board[position] == " ")
{
validMove = true;
board[position] = "o"; // placing o in desired board position
}
else
{
cout << "That position is already occupied." << endl;
cout << displayBoard(board) << endl;
}
}
cout << displayBoard(board) << endl;
if (isGameOver(board))
{
gameOver = true;
}
}// end of validMove while loop
system("pause");
return 0;
}// end of main
// ************************** functions *************************
void displayGameWelcome()
{
cout << "Welcome to Tic Tac Toe v3.2" << endl;\
cout << "by Brett Singley & Nick Canarelli" << endl;
cout << "****************************\n\n\n";
}// end of displayGameWelcome
// checks if game is over
bool isGameOver(string board[9])
{
if (board[0] == "x" && board[1] == "x" && board[2] == "x")
{
cout << endl << "The game is over - x wins" << endl;
return true;
}
else if (board[0] == "o" && board[1] == "o" && board[2] == "o")
{
cout << endl << "The game is over - o wins" << endl;
return true;
}
else if (board[3]=="x" && board[4]=="x" && board[5]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[3]=="o" && board[4]=="o" && board[5]=="o")
{
cout <<endl << "The game is over - o wins" <<endl;
}
else if (board[0]=="x" && board[3]=="x" && board[6]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[0]=="o" && board[3]=="o" && board[6]=="o")
{
cout <<endl << "The game is over - o wins" <<endl;
}
else if (board[6]=="x" && board[7]=="x" && board[8]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[6]=="o" && board[7]=="o" && board[8]=="o")
{
cout <<endl << "The game is over - O wins" <<endl;
}
else if (board[1]=="x" && board[4]=="x" && board[7]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[1]=="o" && board[4]=="o" && board[7]=="o")
{
cout <<endl << "The game is over - O wins" <<endl;
}
else if (board[2]=="x" && board[5]=="x" && board[8]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[2]=="o" && board[5]=="o" && board[8]=="o")
{
cout <<endl << "The game is over - o wins" <<endl;
}
else if (board[0]=="x" && board[4]=="x" && board[8]=="x")
{
cout <<endl << "The game is over - X wins" << endl;
}
else if (board[0]=="o" && board[4]=="o" && board[8]=="o")
{
cout <<endl << "The game is over - o wins" <<endl;
}
else if (board[2]=="x" && board[4]=="x" && board[6]=="x")
{
cout <<endl << "The game is over - X wins" <<endl;
}
else if (board[2]=="o" && board[4]=="o" && board[6]=="o")
{
cout <<endl << "The game is over - o wins" <<endl;
}
else
{
cout << "WOAH!!!!! Tie Game" <<endl;
}
// more to do here (don't forget to check for draw)
return false;
}// end of isGameOver
// displays tic tac toe board in the format
// |0 1 2|
// |3 4 5|
// |6 7 8|
string displayBoard(string board[9])
{
string str = "";
for (int i = 0; i < 9; i++)
{
if (i == 0)
{
str = str + "|" + board[i];
}
else if (i == 2 || i == 5)
{
str = str + board[i] + "|\n|";
}
else if (i == 8)
{
str = str + board[i] + "|\n";
}
else
{
str = str + board[i];
}
}
return str;
}// end of displayBoard
You can simplify checking for a winner by using for loops and realizing that the value in the three spaces are equal (to something other than the initial value). Also, since there are 3 rows and 3 columns, the rows and columns can be checked inside the same for loop:
const char initial_value = ' ';
const unsigned int max_rows_or_columns = 3;
bool Is_Game_Over(int board[9], char& winner)
{
for (unsigned int i = 0; i < max_rows_or_columns; ++i)
{
// Check the row
if ( (board[(i * 3) + 0] == board[(i * 3) + 1])
&& (board[(i * 3) + 1) == board[(i * 3) + 2]))
{
// By transitive property, board[(i * 3) + 0] == board[(i * 3) + 2]
winner = board[(i * 3) + 0];
if (winner != initial_value)
{
break;
}
}
else // Check the columns
{
if ( (board[(0 * 3) + i] == board[(1 * 3) + i])
&& (board[(1 * 3) + i] == board[(2 * 3) + i]))
{
winner = board[(0 * 3) + i];
if (winner != initial_value)
{
break;
}
}
}
bool winner_found = true;
if (i >= max_rows_or_columns)
{
winner_found = false;
}
return winner_found;
}
The checking of the diagonals is left as an exercise for the reader.
Related
I wanted to expand on an older Tic Tac Toe game I made where two players can play versus each other. I want to give the user the option of playing against a difficult AI. The issue is that the AI won't pick the best move all the time. For instance, it will always pick spot 1 if going first. If the user picks spot 2, it will pick spot 4. After this, no matter what the user picks (besides spot 7) the AI won't pick spot 7. Victory for the AI is far from inevitable (the user can still win the game at this point), so that's not the problem.
Any help is appreciated. Thanks!
I'm positive the problem is with my minimax or bestmove functions. It may just be that I haven't properly implemented by minimax function, but I can't spot the issue.
#include <iostream>
#include <iomanip>
#include <string>
#include <array>
// This is a program to play a single game of tic-tac-toe
// between either two human (non-AI) players or an AI.
using namespace std;
void PrintBoard(array <char, 9>);
int programprogress();
int checkwin(array <char, 9>);
int minimax(array <char, 9>, int, int, bool);
int bestMove(array <char, 9>, int);
int Opposite(int);
char PlayerSymbol(int);
const int SIZE = 9;
array <char, SIZE> Pos = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int player_number = 1;
int k = -11, result;
bool AI = false, first;
// Global variables used by 2 or more functions.
// Array had to be initialized with numbers instead of blank spaces
// because the check win function wouldn't work properly.
int main()
{
string userinp;
cout << "This is tic tac toe! Here's your board!" << endl;
PrintBoard(Pos);
cout << "Would you like to play versus an AI? (Y/N)" << endl;
cin >> userinp;
if (userinp[0] == 'Y')
{
cout << "Excellent! Would you like to start first, or second? (F/S)" << endl;
cin >> userinp;
if (userinp[0] == 'F')
{
cout << "You will start first!" << endl;
first = false;
player_number = 2;
}
else
{
cout << "The AI will start first!" << endl;
first = true;
}
AI = true;
}
else
{
cout << "Excellent! Your game will start soon." << endl;
}
result = programprogress();
player_number--;
PrintBoard(Pos);
if (result == 1)
cout << endl << "Player " << player_number << " has won!!!\n";
else if (result == 10)
cout << endl << "The AI has won! Better luck next time!\n";
else if (result = -10)
cout << endl << "You beat the world's best AI! Congratulations!\n";
else
cout << endl << "The game has been drawn!" << endl;
return 0;
}
void PrintBoard(array <char, 9> Pos)
{
system("cls");
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[0] << setw(3) << "|" << setw(3) << Pos[1] << setw(3) << "|" << setw(3) << Pos[2] << " TIC TOE" << endl;
cout << "_____|_____|_____" << endl;
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[3] << setw(3) << "|" << setw(3) << Pos[4] << setw(3) << "|" << setw(3) << Pos[5] << " TAC " << endl;
cout << "_____|_____|_____" << endl;
cout << setw(6) << "|" << setw(6) << "|" << endl << setw(3) << Pos[6] << setw(3) << "|" << setw(3) << Pos[7] << setw(3) << "|" << setw(3) << Pos[8] << " TIC TOE " << endl;
cout << " | |" << endl;
}
int programprogress()
{
while (k == -11 && AI)
{
bool InvalidChoice = false;
char letter;
//player_number = (player_number % 2) ? 1 : 2;
int PlayerChoice;
if (player_number == 2)
{
cout << endl << "What is your move?" << endl;
cin >> PlayerChoice;
while ((PlayerChoice < 1) || (PlayerChoice > 9))
{
cout << "That's an invalid choice! Please choose a number that is 1-9!" << endl;
cin >> PlayerChoice;
}
PlayerChoice--;
letter = (!first) ? 'X' : 'O';
if (Pos[PlayerChoice] == '1' || Pos[PlayerChoice] == '2' || Pos[PlayerChoice] == '3' || Pos[PlayerChoice] == '4' || Pos[PlayerChoice] == '5' || Pos[PlayerChoice] == '6' || Pos[PlayerChoice] == '7' || Pos[PlayerChoice] == '8' || Pos[PlayerChoice] == '9')
{
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
}
/*else
{
cout << "That space is already taken!" << endl;
player_number--;
}*/
k = checkwin(Pos);
if (k != -11)
k = k * -10;
player_number = 1;
}
else
{
cout << endl << "The computer has made its move!" << endl;
letter = (first) ? 'X' : 'O';
if (first)
PlayerChoice = bestMove(Pos, 1);
else
PlayerChoice = bestMove(Pos, 2);
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
k = checkwin(Pos);
if (k != -11)
k = k * 10;
player_number = 2;
}
}
while (k == -11 && !AI)
{
bool InvalidChoice = false;
char letter;
player_number = (player_number % 2) ? 1 : 2;
int PlayerChoice;
cout << endl << "What's player " << player_number << "'s move?" << endl;
cin >> PlayerChoice;
while ((PlayerChoice < 1) || (PlayerChoice > 9))
{
cout << "That's an invalid choice! Please choose a number that is 1-9!" << endl;
cin >> PlayerChoice;
}
PlayerChoice--;
letter = (player_number == 1) ? 'X' : 'O';
if (Pos[PlayerChoice] == '1' || Pos[PlayerChoice] == '2' || Pos[PlayerChoice] == '3' || Pos[PlayerChoice] == '4' || Pos[PlayerChoice] == '5' || Pos[PlayerChoice] == '6' || Pos[PlayerChoice] == '7' || Pos[PlayerChoice] == '8' || Pos[PlayerChoice] == '9')
{
Pos[PlayerChoice] = letter;
PrintBoard(Pos);
}
else
{
cout << "That space is already taken!" << endl;
player_number--;
}
k = checkwin(Pos);
player_number++;
}
return k;
}
int checkwin(array <char, SIZE> Pos)
{
if (Pos[0] == Pos[1] && Pos[1] == Pos[2])
return 1;
else if (Pos[3] == Pos[4] && Pos[4] == Pos[5])
return 1;
else if (Pos[6] == Pos[7] && Pos[7] == Pos[8])
return 1;
else if (Pos[0] == Pos[3] && Pos[3] == Pos[6])
return 1;
else if (Pos[1] == Pos[4] && Pos[4] == Pos[7])
return 1;
else if (Pos[2] == Pos[5] && Pos[5] == Pos[8])
return 1;
else if (Pos[0] == Pos[4] && Pos[4] == Pos[8])
return 1;
else if (Pos[2] == Pos[4] && Pos[4] == Pos[6])
return 1;
else if (Pos[0] != '1' && Pos[1] != '2' && Pos[2] != '3'
&& Pos[3] != '4' && Pos[4] != '5' && Pos[5] != '6'
&& Pos[6] != '7' && Pos[7] != '8' && Pos[8] != '9')
return 0;
else
return -11;
}
int minimax(array <char, SIZE> newpos, int depth, int player, bool opp)
{
int scale = 0;
if ((player == 1 && first) || (player == 2 && !first))
scale = 10;
else
scale = -10;
//cout << scale;
int score = scale*checkwin(newpos);
if (score < 0)
score += depth;
else if (score > 0)
score -= depth;
if (score == -10 || score == 10 || score == 0)
return score;
if (opp)
{
int best = -1000;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
best = max(best, minimax(newpos, depth + 1, Opposite(player), !opp));
newpos[i] = temp;
}
}
return best;
}
else
{
int best = 1000;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
best = min(best, minimax(newpos, depth + 1, Opposite(player), !opp));
newpos[i] = temp;
}
}
return best;
}
}
int bestMove(array <char, SIZE> newpos, int player)
{
int best = -1000;
int bestpos = -1;
for (int i = 0; i < SIZE; i++)
{
if (newpos[i] != 'X' && newpos[i] != 'O')
{
char temp = newpos[i];
newpos[i] = PlayerSymbol(player);
int move = minimax(newpos, 0, player, !first);
newpos[i] = temp;
if (move > best)
{
//cout << "I like pineapple on pizza" << endl;
bestpos = i;
best = move;
}
/*if (move == best)
{
cout << "I like pineapple on pizza" << endl;
}*/
}
}
cout << bestpos;
return bestpos;
}
int Opposite(int x)
{
if (x == 1)
return 2;
else
return 1;
}
char PlayerSymbol(int x)
{
if (x == 1)
return 'X';
else
return 'O';
}
An out of bounds error due to the -1 value of bestpos. I'm not sure how to change this, though.
There are 4 issues that I could find. Solving them seems to lead to the intended behavior.
Firstly, when you call minimax(newpos, 0, player, !first); from inside the bestMove function, you pass player rather than Opposite(player), indicating that the first minimax step will be performed by the same player as the bestMove step. In other words: The AI makes two successive moves for itself. Therefore player needs to be changed to Opposite(player).
Secondly, minimax has a bool variable named opp that seems to indicate whether it is the AI or its opponent making the move. For the first minimax step, opp is set to !first, indicating that only if the AI goes first, the opponent will make a move after the AI. That is incorrect. It is always the opponent making a move after the AI. So bestMove should call minimax with true rather than !first. As an aside, opp is redundant, because you can use (player == 1 && first) || (player == 2 && !first) to check whether it's the AI or its opponent making the move.
Thirdly, the scale is set the wrong way around. With (player == 1 && first) || (player == 2 && !first) you check whether its the AI making a move. But you do that in the next minimax step, after the potentially winning move. So if the AI is making a move and the game is already won, then the opponent made the winning move, not the AI. Ergo, the scale should be
if ((player == 1 && first) || (player == 2 && !first))
scale = -10;
else
scale = 10;
instead.
Lastly, you check whether the score is 10 or -10 after adding the depth. If depth is not 0, then this check will always fail. So beyond depth 0, the AI can only see a draw, never a win. You could instead write
if (score == -10 || score == 10 || score == 0)
{
if (score < 0)
score += depth;
else if (score > 0)
score -= depth;
return score;
}
Hope this answers your question fully.
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/
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;
}
I have 2 things that aren't working with this code. The first thing is that in my second do-while loop in main, when I input 'g' or 'G' and I put in coordinates and select if it is left or right it loops continuously.
My second thing that doesn't work right is that when I shoot my laser, a baffle should turn it and make it go a different direction. This works but it doesn't turn the laser until the box after the baffle is located. I am so stuck with this, any help would be great, and anything that you also see that I should fix would be greatly appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
struct velocity
{
int X = 0, Y = 0;
};
struct position
{
int X = 0, Y = 0;
void addVelocity(velocity V)
{
X += V.X;
Y += V.Y;
}
};
int gameBoard[10][10];
int guessBoard[10][10];
int random(int);
void laser(int&);
int boxNum(position, velocity);
position calcExitPos(velocity&, int&);
position moveLaser(position&, velocity V);
velocity checkPos(position, velocity&);
bool checkWall(position, velocity);
int main()
{
char level, action;
int num = 0;
int score = 0, guess = 0, shots = 0, LorR = 0;
int X = 0, Y = 0;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
gameBoard[i][j] = 0;
}
}
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
guessBoard[i][j] = 0;
}
}
cout << "Welcome to the Baffle Game." << endl;
cout << " 10 11 12 13 14 15 16 17 18 19" << endl;
cout << "9|___|___|___|___|___|___|___|___|___|___|20" << endl;
cout << "8|___|___|___|___|___|___|___|___|___|___|21" << endl;
cout << "7|___|___|___|___|___|___|___|___|___|___|22" << endl;
cout << "6|___|___|___|___|___|___|___|___|___|___|23" << endl;
cout << "5|___|___|___|___|___|___|___|___|___|___|24" << endl;
cout << "4|___|___|___|___|___|___|___|___|___|___|25" << endl;
cout << "3|___|___|___|___|___|___|___|___|___|___|26" << endl;
cout << "2|___|___|___|___|___|___|___|___|___|___|27" << endl;
cout << "1|___|___|___|___|___|___|___|___|___|___|28" << endl;
cout << "0|___|___|___|___|___|___|___|___|___|___|29" << endl;
cout << " 39 38 37 36 35 34 33 32 31 30" << endl << endl;
cout << "This is the game board, you will shoot lasers and try to find all the baffles. " << endl << endl;
//cout << "For beginner there are 4 baffles, for intermediate there are 7 baffles and for advanced there are 10 baffles." << endl;
//cout << "Please type B for beginner, I for intermediate, and A for advanced" << endl;
do
{
cout << "For beginner there are 4 baffles, for intermediate there are 7 baffles" << endl;
cout << "and for advanced there are 10 baffles." << endl;
cout << "Please type B for beginner, I for intermediate, and A for advanced" << endl;
cin >> level;
} while (level != 'b' && level != 'B' && level != 'i' && level != 'I' && level != 'a' && level != 'A');
if (level == 'B' || level == 'b')
{
//Baffles equals 4
num = random(4); // function returns to num
}
else if(level == 'I' || level == 'i')
{
//Baffles equals 7
num = random(7);
}
else
{
//Baffles equals 10
num = random(10);
}
cout << "We will begin the game now." << endl;
cout << "Here are some commands that you will need to know to play." << endl;
cout << "L: Laser shot, then pick a number on the board to shoot the laser from." << endl;
cout << "G: Guess the location of one baffle with coordinance and L or R to choose a left or right baffle." << endl;
cout << "S: When you want me to print the score that you have." << endl;
cout << "P: Print the board showing the baffles that you have already found." << endl;
cout << "Q: Quit the game at any time" << endl;
cout << "C: This shows you the board with all the baffles and which direction they are." << endl;
do
{
cout << "Please type in your command." << endl;
cin >> action;
if (action == 'L' || action == 'l')
{
laser(shots);
}
else if (action == 'G' || action == 'g')
{
cout << "We will guess where the baffle is." << endl;
cout << "Please enter the X coordinate." << endl;
cin >> X;
cout << "Please enter the Y coordinate." << endl;
cin >> Y;
//cout << gameBoard[X][Y] << endl;
cout << "Please enter L and R for Left and Right Baffles." << endl;
cin >> LorR;
//cout << gameBoard[X][Y];
if (gameBoard[X][Y] == 1)//Right
{
//cout << "1" << endl;
if (LorR == 'R' || LorR == 'r')
{
cout << "Good job you got it correct." << endl;
guessBoard[X][Y] = 'R';
//points++
}
else
cout << "Wrong!" << endl;
}
else if (gameBoard[X][Y] == 2)//Left
{
//cout << "2" << endl;
if (LorR == 'L' || LorR == 'l')
{
cout << "Good job you got it correct." << endl;
guessBoard[X][Y] = 'L';
//points++
}
else
cout << "Wrong!" << endl;
}
else if (gameBoard[X][Y] == 0)
{
cout << "Your are wrong!" << endl;
}
}
else if (action == 'S' || action == 's')
{
cout << "Number of shots: " << shots << endl;
cout << "Number of guesses: " << guess << endl;
cout << "Current score: " << endl;//Get score
}
else if (action == 'P' || action == 'p')
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << setw(2) << guessBoard[i][j] << " ";
}
cout << endl;
}
}
else if (action == 'C' || action == 'c')
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << setw(2) << gameBoard[i][j] << " ";
}
cout << endl;
}
}
else if (action == 'q' || action == 'Q')
{
}
else if (action != 'q' && action != 'Q')
{
cout << "*** Illegal command - Try again ***" << endl;
}
cout << "loop" << endl;
}
while (action == 'q' || action == 'Q' || action == 'L' || action == 'l' || action == 'G' || action == 'g' ||
action == 'S' || action == 's' || action == 'P' || action == 'p' || action == 'C' || action == 'c');
}
//This function finds a random number for the find a random index
// in the array.
int random(int randnum)
{
unsigned seed = time(0); //get the system time.
srand(seed); //seed the random number generator.
int x, y, randomNum = 0;
int count;
for (count = 0; count < randnum; count++)
{
do
{
x = (rand() % (9 - 0 + 1)) + 0;
y = (rand() % (9 - 0 + 1)) + 0;
} while (gameBoard[x][y] != 0);
cout << "(" << x << "," << y << ")" << endl;
randomNum = rand();
gameBoard[x][y] = (randomNum % 2) + 1;
cout << gameBoard[x][y] << endl;
//2 = Left baffle
//1 = right baffle
}
return gameBoard[x][y];
}
void laser(int &shots) //Shoots a laser where user asks it to
{
int shoot;
cout << "Please input what number you want to shoot the laser from." << endl;
cin >> shoot;
shots++;
velocity V;
position P = calcExitPos(V,shoot);
//checkPos(P, V);
//cout << "1" << endl;
do
{
checkPos(P, V);
moveLaser(P, V);
//cout << "1" << endl;
} while (checkWall(P, V) == false);
cout << "Laser shot #" << shots << " exited the box at " << boxNum(P, V) << endl;
}
int boxNum(position P, velocity V) //Figures out what number the laser exits
{
if (P.X == 0 && V.X == -1)
{
return 9 - P.Y;
}
else if (P.Y == 0 && V.Y == -1)
{
return 10 + P.X;
}
else if (P.X == 9 && V.X == 1)
{
return P.Y + 20;
}
else if (P.Y == 9 && V.Y == 1)
{
return 39 - P.X;
}
}
position calcExitPos(velocity &V, int &box)//Figures out where the laser shoots from by the number the user inputs
{
position P1;
if (box >= 0 && box <= 9)
{
V.X = 1;
V.Y = 0;
P1.X = 0;
P1.Y = (9 - box);
}
else if (box >= 10 && box <= 19)
{
V.X = 0;
V.Y = 1;
P1.X = (box - 10);
P1.Y = 0;
}
else if (box >= 20 && box <= 29)
{
V.X = -1;
V.Y = 0;
P1.X = 9;
P1.Y = (box - 20);
}
else if (box >= 30 && box <= 39)
{
V.X = 0;
V.Y = -1;
P1.X = (39 - box);
P1.Y = 9;
}
return P1;
}
position moveLaser(position &P, velocity V)
{
int baffletype = gameBoard[P.X][P.Y];
if (baffletype == 1)//Right
{
if (V.X == 1)
{
V.Y = -1;
V.X = 0;
P.Y--;
}
else if (V.X == -1)
{
V.Y = 1;
V.X = 0;
P.Y++;
}
else if (V.Y == 1)
{
V.X = -1;
V.Y = 0;
P.X--;
}
else if (V.Y == -1)
{
V.X = 1;
V.Y = 0;
P.X++;
}
}
else if (baffletype == 2)//Left
{
if (V.X == 1)
{
V.Y = 1;
V.X = 0;
P.Y++;
}
else if (V.X == -1)
{
V.Y = -1;
V.X = 0;
P.Y--;
}
else if (V.Y == 1)
{
V.X = 1;
V.Y = 0;
P.X++;
}
else if (V.Y == -1)
{
V.X = -1;
V.Y = 0;
P.X--;
}
}
else if (baffletype == 0)
{
if (V.X == 1)
{
V.Y = 0;
V.X = 1;
P.X++;
}
else if (V.X == -1)
{
V.Y = 0;
V.X = -1;
P.X--;
}
else if (V.Y == 1)
{
V.X = 0;
V.Y = 1;
P.Y++;
}
else if (V.Y == -1)
{
V.X = 0;
V.Y = -1;
P.Y--;
}
}
cout << "(" << P.X << ","<< P.Y << ")" << endl;
return P;
}
velocity checkPos(position P, velocity &V) //Directs the laser when the laser hits a baffle
{
int baffletype = gameBoard[P.X][P.Y];
if (baffletype == 1)//Right
{
if (V.X == 1)
{
V.Y = -1;
V.X = 0;
}
else if (V.X == -1)
{
V.Y = 1;
V.X = 0;
}
else if (V.Y == 1)
{
V.X = -1;
V.Y = 0;
}
else if (V.Y == -1)
{
V.X = 1;
V.Y = 0;
}
}
else if (baffletype == 2)//Left
{
if (V.X == 1)
{
V.Y = 1;
V.X = 0;
}
else if (V.X == -1)
{
V.Y = -1;
V.X = 0;
}
else if (V.Y == 1)
{
V.X = 1;
V.Y = 0;
}
else if (V.Y == -1)
{
V.X = -1;
V.Y = 0;
}
}
else if (baffletype == 0)
{
if (V.X == 1)
{
V.Y = 0;
V.X = 1;
P.X++;
}
else if (V.X == -1)
{
V.Y = 0;
V.X = -1;
P.X--;
}
else if (V.Y == 1)
{
V.X = 0;
V.Y = 1;
P.Y++;
}
else if (V.Y == -1)
{
V.X = 0;
V.Y = -1;
P.Y--;
}
}
//cout << "( " << P.X << ", " << P.Y << ")" << endl;
return V;
}
bool checkWall(position P, velocity V) //Checks to see if the laser hits the wall
{
//cout << "2" << endl;
P.addVelocity(V);
return (P.X > 9 || P.X < 0 || P.Y > 9 || P.Y < 0); //Checks to see if the next position is out of bounds
}
I don't have a complete solution for you but a couple of things.
You should make your while loop test simpler.
How about this (pseudocode):
bool done = false;
while (!done) {
// Process action loop
cin >> action;
action = toupper(action); // Make everything upper case
processTheAction(action);
done = areWeDoneYet(action);
}
Break up the complex "are we done yet" task and other things into functions. (Divide and conquer)
bool areWeDoneYet(action) {
switch (action) {
case A:
case B:
... (cases where we are not done)
return false;
case E:
case F:
... (cases where we are done)
return true;
}
}
Make your "event loop" simple. Have it call a complex function
"ProcessAction" That way you can tell if you are busy processing when you have an issue, or if your having an issue with the event loop.
void processTheAction( action ) {
switch (action) {
case A:
case a: // Optional method if you don't do topper on Action
// Code for action 'A' goes here
// If a *lot* of code make a function like "ProcessActionA()"
break;
case B:
case b: // not needed if you do topper
// Code for action 'B' goes here
break;
default:
printf("I'm hosed cause I forgot to manage action [%c]\n",
action);
}
}
Don't know if this helps, but it might help you to break down the problem.
Im currently making a one-armed bandit game and this is what it's supposed to do:
The user should be able to put money into the machine, 50, 100 or 500
The user should be able to bet money for each game
After the user have betted money symbols should be randomized in a field like this:
[ o ] [ p ] [ x ]
[ x ] [ x ] [ x ]
[ x ] [ o ] [ x ]
(1 columns/ lines wins 2x money, 2 columns/ lines wins 4x money etc.)
This field should each time be randomized with letters , also a two-dimensional array should be used to represent the gamearea.
I've ran into some problems, basically after I bet some money the game closes and I cant see any errors etc, any help that clarifies this problem would be greatly appreciated, aswell as any improvements I could do to my code etc.
This is my code:
#include <iostream>
#include <ctime>
using namespace std;
int main(int args, const char* argv[])
{
int svar = 0;
int bokstav = 0;
int insert;
int build;
int bet;
int credit;
int array;
int jackpot;
int tal;
int spin_1x = 0;
int spin_1y = 0;
int spin_2x = 0;
int spin_2y = 0;
cout << "Welcome to the one-armed bandit!" << endl;
cout << endl;
cout << "To play start by betting some money!" << endl;
cout << endl;
cout << "Insert 50/ 100/ 500 kr to your account!" << endl;
cout << endl;
cin >> insert;
while (insert < 50 || insert > 500)
{
cout << "You either inserted to little or to much" << endl;
cin >> insert;
}
cout << "You inserted" << insert;
cout << endl;
while (insert > 50)
{
cout << "Bet some money to play!" << endl;
cout << endl;
cin >> bet;
cout << endl;
while (bet !=50 && bet !=100 && bet !=500)
{
if (bet == 50) return 1;
{
cout << "You have betted 50 kr!" << endl;
}
{
if (bet == 100) return 2;
{
cout << "You have betted 100 kr!" << endl;
}
{
if (bet == 500)
{
cout << "You have betted 500 kr!" << endl;
}
char a = '£';
char b = '$';
char c = '*';
char build [4][4] = {
{ ' ', 'A', 'B', 'C',},
{ '1', ' ', ' ', ' ',},
{ '2', ' ', ' ', ' ',},
{ '3', ' ', ' ', ' ',},
};
int array();
cout << build[0][1] << " " << build[0][2] <<" "<< build[0][3] <<" " << endl;
cout << build[1][0] <<"|_|" <<"|_|" << "|_|" << endl
<< build[2][0] <<"|_|" <<"|_|" << "|_|" << endl
<< build[3][0] <<"|_|" <<"|_|" << "|_|" << endl;
return 0;
srand(time(0));
spin_1x=rand() % 4 + 1;
spin_1y=rand() % 4 + 1;
spin_2x=rand() % 4 + 1;
spin_2y=rand() % 4 + 1;
int y = 0;
int x = 0;
if (x == spin_1x && y == spin_1y)
{
build[x][y]='0';
cout << "Congrats you won!" << endl;
}
else if (x == spin_2x && y == spin_2y)
cout << "Congrats you won!" << endl;
cout << endl;
cout << "JACKPOT!" << endl;
{
if (insert <= 0)
{
cout << "You dont have any money left! Game's over!" << endl;
}
int insert;
if ((a == 7 && b == 7 && c == 7))
{
cout << "You have won x2 your bet!($" << ( bet*2) << ")" << endl;
credit = credit + (bet*2);
}
else if ((a == b == c) && ! (a == 7 && b == 7 && c == 7))
{
cout << "You have won x4 your bet!($" << (bet*4) << ")" << endl;
credit = credit + (bet*4);
}
else if ((a == b || a == c || b == c) && !(a == b == c) && !(a == 7 && b == 7 && c == 7))
{
credit = credit + (bet*8);
cout << "You have won x8 your bet!($" << (bet*8) << ")" << endl;
}
else if ((a == b || a == c || b == c) && ! (a == b == c) && ! (a == 7 && b == 7 && c == 7))
{
credit = credit + (bet*16);
cout << "You have won x16 your bet!($" << (bet*16) << ")" << endl;
}
else if (( a == b || a == c || b == c) && ! (a == b == c) && ! (a == 7 && b == 7 && c == 7))
{
credit = credit + (bet*128);
cout << "You have won x128 your bet!($" << (bet*128) << ")" << endl;
}
else
{
cout << "You have lost your betting!($-" << bet << ")" << endl;
credit = credit - bet;
}
return credit;
}
}
return 0;
}
}
}
}
The issue, as others stated, is that you are returning from your main which terminates the program. My suggestion:
Move your game logic into a separate method(s)
Place the logic call inside a while loop in the main that checks if the player wants to play again
Only return from main when the player wants to stop
Example partial code (you should get the idea):
void printWelcome( )
{
std::cout << "Welcome to the One-Armed Bandit!" << std::endl;
// etc.
}
int getBet( )
{
int betAmount;
std::cout << "To play start by betting some money!\n"
<< "Insert 50/ 100/ 500 kr to your account!" << std::endl;
std::cin >> betAmount;
return betAmount;
}
void playGame( )
{
// All of your game logic in here
}
bool wantsToPlay( )
{
std::cout << "Do you want to play again? (y/n)" << std::endl;
char response;
std::cin >> response;
if( response == 'y' )
{
return true;
}
else
{
return false;
}
}
int main( int argc, char** argv )
{
int betAmount = 0;
printWelcome( );
do
{
betAmount = getBet( );
if( betAmount != 50 && betAmount != 100 && betAmount != 150 )
{
// Restart the game loop (ask for bet again)
continue;
}
playGame( );
} while( wantsToPlay( ) );
std::cout << "Thank you for playing!" << std::endl;
return 0;
}
Your console is closing because the program is terminated when the main function hits a return , put a cin before each return. That will "pause" the application just before it terminates letting you see your traces.
Run your program by yourself instead of computer and you will see why its closing so fast. Remember that return in main() means "close program now".