Need help with a simple AI

I created a TicTacToe game, and the AI in it is difficult, but predictable. Not only that, but it is buggy. I want your opinion on the AI, and any tips to make it better. Any help is appreciated!

Code is in the responses!
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <cstdlib>

using namespace std;

enum ttts {TTTS_BLANK, TTTS_O, TTTS_X};
const string spacer = "#";
const string ender = "\n";
const string ttts_blank = " ";
const string ttts_o = "O";
const string ttts_x = "X";

bool debug = false;

struct player {
	int id;
	string name;
	bool turn;
	bool ai;
};


// AI Checks to see if the player is close to winning.
int ai_player(int board[9]) {
	int place_to;
	int random = rand() % 9;
	if ((board[1] == TTTS_X && board[2] == TTTS_X) && board[0] == TTTS_BLANK || (board[6] == TTTS_X && board[3] == TTTS_X) && board[0] == TTTS_BLANK || (board[4] == TTTS_X && board[8] == TTTS_X) && board[0] == TTTS_BLANK) {
		place_to = 0;
	} else if ((board[0] == TTTS_X && board[2] == TTTS_X) && board[1] == TTTS_BLANK || (board[4] == TTTS_X && board[7] == TTTS_X) &&board[1]==TTTS_BLANK) {
		place_to = 1;
	} else if ((board[0] == TTTS_X && board[1] == TTTS_X) && board[2] == TTTS_BLANK || (board[6] == TTTS_X && board[4] == TTTS_X) && board[2] == TTTS_BLANK|| (board[5] == TTTS_X && board[8] == TTTS_X) && board[2] == TTTS_BLANK) {
		place_to = 2;
	} else if ((board[0] == TTTS_X && board[6] == TTTS_X) && board[3] == TTTS_BLANK || (board[4] == TTTS_X && board[5] == TTTS_X) && board[3] == TTTS_BLANK) {
		place_to = 3;
	} else if ((board[0] == TTTS_X && board[8] == TTTS_X) && board[4] == TTTS_BLANK || (board[2] == TTTS_X && board[6] == TTTS_X) && board[4] == TTTS_BLANK || (board[3] == TTTS_X && board[5] == TTTS_X) && board[4] == TTTS_BLANK) {
		place_to = 4;
	} else if ((board[2] == TTTS_X && board[8] == TTTS_X) && board[5] == TTTS_BLANK || (board[3] == TTTS_X && board[4] == TTTS_X) && board[5] == TTTS_BLANK) {
		place_to = 5;
	} else if ((board[0] == TTTS_X && board[3] == TTTS_X) && board[6] == TTTS_BLANK || (board[4] == TTTS_X && board[2] == TTTS_X) && board[6] == TTTS_BLANK || (board[8] == TTTS_X && board[7] == TTTS_X) && board[6] == TTTS_BLANK) {
		place_to = 6;
	} else if ((board[6] == TTTS_X && board[8] == TTTS_X) && board[7] == TTTS_BLANK || (board[1] == TTTS_X && board[4] == TTTS_X) && board[7] == TTTS_BLANK) { 
		place_to = 7;
	} else if ((board[0] == TTTS_X && board[4] == TTTS_X) && board[8] == TTTS_BLANK || (board[6] == TTTS_X && board[7] == TTTS_X) && board[8] == TTTS_BLANK || (board[2] == TTTS_X && board[5] == TTTS_X) && board[8] == TTTS_BLANK) {
		place_to = 8;
	} else if (board[random] == TTTS_BLANK) {
		place_to = random;
	}
	return place_to;
}


//Checks for victory
int check_victory(int board[9]) {
	int victor;
	if (debug) {
	}
	if ((board[0] == TTTS_O && board[1] == TTTS_O && board[2] == TTTS_O) || (board[0] == TTTS_O && board[4] == TTTS_O && board[8] == TTTS_O) || (board[0] == TTTS_O && board[3] == TTTS_O && board[6] == TTTS_O) || (board[1] == TTTS_O && board[4] == TTTS_O && board[7] == TTTS_O) || (board[2] == TTTS_O && board[5] == TTTS_O && board[8] == TTTS_O) || (board[2] == TTTS_O && board[4] == TTTS_O && board[6] == TTTS_O) || (board[3] == TTTS_O && board[4] == TTTS_O && board[5] == TTTS_O) || (board[6] == TTTS_O && board[7] == TTTS_O && board [8] == TTTS_O)) {
		victor = 1;
	} else if ((board[0] == TTTS_X && board[1] == TTTS_X && board[2] == TTTS_X) || (board[0] == TTTS_X && board[4] == TTTS_X && board[8] == TTTS_X) || (board[0] == TTTS_X && board[3] == TTTS_X && board[6] == TTTS_X) || (board[1] == TTTS_X && board[4] == TTTS_X && board[7] == TTTS_X) || (board[2] == TTTS_X && board[5] == TTTS_X && board[8] == TTTS_X) || (board[2] == TTTS_X && board[4] == TTTS_X && board[6] == TTTS_X) || (board[3] == TTTS_X && board[4] == TTTS_X && board[5] == TTTS_X) || (board[6] == TTTS_X && board[7] == TTTS_X && board [8] == TTTS_X)) {
		victor = 0;
	} else {
		victor = 2;
		if (debug) {
		}
	}
	return victor;
}

//Where does the player want to put his token
int get_space(int player) {
	int space;
	START:
	if (player == 0) {
		cout << ender << "\tWhere do you want to put a X: ";
		cin >> space;
	} else if (player == 1) {
		cout << ender << "\tWhere do you want to put a O: ";
		cin >> space;
	}
	return space;
}


// Draw the tokens
void draw_tile(int ttts_board_type, int where_are_we_in_the_line) {
	switch (ttts_board_type) {
		case TTTS_BLANK:
			if ( (where_are_we_in_the_line == 1 || where_are_we_in_the_line == 0)) {
				cout << ttts_blank << spacer;
			} else if (where_are_we_in_the_line == 2) {
				cout << ttts_blank;
			}
			break;
		case TTTS_X:
			if ( (where_are_we_in_the_line == 1 || where_are_we_in_the_line == 0)) {
				cout << ttts_x << spacer;
			} else if ( (where_are_we_in_the_line == 2)) {
				cout << ttts_x;
			}
			break;
		case TTTS_O:
			if ( (where_are_we_in_the_line == 1 || where_are_we_in_the_line == 0)) {
				cout << ttts_o << spacer;
			} else if (where_are_we_in_the_line == 2) {
				cout << ttts_o;
			}
			break;
	}
}

// Spits out 5 #
void draw_line() {
	cout << spacer << spacer << spacer << spacer << spacer << endl;
}

// Creates the board.
void draw_board(int ttts_board_draw [9], player player_o, player player_x) {
	if (!debug) {
		system("cls");
	}	
	int i = 0;
	draw_tile(ttts_board_draw[i], 0);
	i++;
	draw_tile(ttts_board_draw[i], 1);
	i++;
	draw_tile(ttts_board_draw[i], 2);
	cout << "\tPlayer X: " << player_x.name << ender;
	i++;
	draw_line();
	draw_tile(ttts_board_draw[i], 0);
	i++;
	draw_tile(ttts_board_draw[i], 1);
	i++;
	draw_tile(ttts_board_draw[i], 2);
	cout << "\tPlayer O: " << player_o.name << ender;
	i++;
	draw_line();
	draw_tile(ttts_board_draw[i], 0);
	i++;
	draw_tile(ttts_board_draw[i], 1);
	i++;
	draw_tile(ttts_board_draw[i], 2);
	if (true) {
		cout << "\tDEBUG INFO: " << player_o.ai << ender;
	}
	i++;
}

I am putting the main loop into a second post to keep the character count down...
The main loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Ugh.
int main() {
	gameStart:
	int ttts_board [9] = {TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK, TTTS_BLANK};
	int plays = 0;
	bool victory = false;
	bool running = true;
	int player_input;
	player player_x;
	player player_o;
	string continueg;
	system("cls");
	cout << "Please enter player 1's name: ";
	cin >> player_x.name;
	player_x.turn = true;
	player_x.id = 0;
	cout << "Please enter player 2's name: ";
	cin >> player_o.name;
	player_o.turn = false;
	player_o.id = 1;
	if (player_o.name == "ai" || player_o.name == "AI" || player_o.name == "Ai" || player_o.name == "aI")
		player_o.ai = true;
	if (player_x.name == "ai" || player_x.name == "AI" || player_x.name == "Ai" || player_x.name == "aI")
		player_x.ai = true;
	do {
		draw_board(ttts_board, player_o, player_x);
		if (player_x.turn) {
			int space;
			/*if (player_x.ai) {
				space = ai_player_x(ttts_board);
			} else {*/
				space = get_space(0);
			//}
			if (ttts_board[space] == TTTS_BLANK) {
				ttts_board[space] = TTTS_X;
				player_x.turn = false;
				player_o.turn = true;
				plays++;
			}
		} else if (player_o.turn) {
			int space;
			if (player_o.ai) {
				space = ai_player(ttts_board);
			} else {
				space = get_space(1);
			}
			if (debug) {
				cout << "\tIf AI is on, then why are we here?" << ender;
			}
			if (ttts_board[space] == TTTS_BLANK) {
				ttts_board[space] = TTTS_O;
				player_x.turn = true;
				player_o.turn = false;
				plays++;
			}
		}
		if (check_victory(ttts_board) == 0) {
			draw_board(ttts_board, player_o, player_x);
			cout << "Victory for " << player_x.name << "!" << ender << "Want to keep playing (Y/N) ";
			cin >> continueg;
			if (continueg == "Y" || continueg == "y") {
				goto gameStart;
			} else if (continueg == "N" || continueg == "n") {
				running = false;
			}
		} else if (check_victory(ttts_board) == 1) {
			draw_board(ttts_board, player_o, player_x);
			cout << "Victory for " <<player_o.name << "!" << ender << "Want to keep playing (Y/N) ";
			cin >> continueg;
			if (continueg == "Y" || continueg == "y") {
				goto gameStart;
			} else if (continueg == "N" || continueg == "n") {
				running = false;
			}
		} else if (check_victory(ttts_board) == 2 && plays == 9) {
			cout << "Cats Game" << ender << "Want to keep playing (Y/N) ";
			cin >> continueg;
			if (continueg == "Y" || continueg == "y") {
				goto gameStart;
			} else if (continueg == "N" || continueg == "n")
				running = false;
		}
	} while (running);
	return 0;
}
Topic archived. No new replies allowed.