ArrayGame. Why doesn't it update the print? - c

This is my C Programming assignment. We're required to build a simple game that uses array. Our game is like the popular minesweeper game. At first, we initialise the 20*50 array area. Then we put some bombs randomly in the map. In the game, the player is required to travel from the starting point to the ending point to win the game. When the player moves, the movement will make the arrays hidden so that the user knows where did he start. However, in my case, the system doesn't update and make the array empty after the player moves. Can anyone help me with my 's' code? What is wrong?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define iMAX 20
#define jMAX 50
char array[20][50];
int i; //row
int j; //column
int z; //bomb
int n; //steps counter
int o; //x
int p; //y
o = 0;
p = 0;
int level;
int bomb;
char move;
int steps;
int main() {
printf("Welcome to the BombArray Game!\n");
printf("\nLevel 1 Begineer : 50 bombs\nLevel 2 Intermediate : 100 bombs\nLevel 3 Advance : 200 bombs\n");
printf("\nI want to challenge level ");
scanf_s("%d", &level);
printf("\n");
srand(time(NULL));
for (i = 0; i < 20; i++) {
for (j = 0; j < 50; j++) {
array[i][j] = '*';
}
}
array[0][0] = 'S';
array[19][49] = 'E';
if (level == 1) {
bomb = 50;
}
else if (level == 2) {
bomb = 100;
}
else if (level == 3) {
bomb = 200;
}
for (z = 0; z < bomb; z++) {
i = rand() % 20;
j = rand() % 50;
array[i][j] = '1';
}
do {
system("cls");
for (i = 0; i < iMAX; i++) {
for (j = 0; j < jMAX; j++) {
if (array[i][j] == 'S') {
printf("S");
}
else if (array[i][j] == '*') {
printf("*");
}
else if (array[i][j] == '1') {
printf("*");
}
else if (array[i][j] == 'E') {
printf("E");
}
else if (array[i][j] == '2') {
printf(" ");
}
}
printf("\n");
}
printf("\n\nMoving direction (w:up s:down a:left d:right e:exit): ");
scanf_s(" %c", &move);
printf("Steps? ");
scanf_s("%d", &steps);
if (move == 's') {
for (n = 0; n < steps; n++) {
i = o;
j = p;
i++;
array[i][j] = '2';
o = i;
p = j;
}
}
} while (array[19][49] != 2);
return 0;
}

if (move == 's') {
array[o][p] = '2';
for (n = 0; n < steps; n++) {
i = o;
j = p;
i++;
array[i][j] = '2';
o = i;
p = j;
}
array[o][p] = 'S';
}
You have to delete the S at the Start position and write it at the end position when you move
Some additional things: You don't need that much variables. You can remove i and j (or o and p).
If you enter something others than 1-3 for the level you will have an undefined number of bombs (if you declare the bomb variable as a local variable), therefore you should make a default case.
You never look if you are hitting a bomb, you just overwrite array[i][j] without prove if there's a bomb.
better:
if (move == 's') {
array[i][j] = '2';
for (n = 0; n < steps; n++) {
i++;
if (array[i][j] == '1') {
printf("bomb\n");
return 0;
}
array[i][j] = '2';
}
array[i][j] = 'S';
}

Related

variables in c changing value randomly

I'm learning C at school, and as homework I have to write the tictactoe game. No problem with the "algorithm", but I do not understand why if I change the order of the variables declaration, the program output drastically changes or even the programme stops working. For example, if I swap line 12 with line 13, the element of the array coord change values at random points of the programme. Can someone explain me why this happen?
#include <stdio.h>
#define DIM 3
#define MAX 11
int main(void) {
char c;
int state = 0; //Variable for the switch case
int nC, nR; //Variables used to count how many X or O there are in the rows and columns of the grid
int i, j;
int coord[2] = {0, 0}; //Array for the coordinates
char grid[DIM][DIM]; //Grid 3x3
char player1[MAX] = "", player2[MAX] = ""; //Name of the players
printf("Player 1, insert your name (max 10 characters): ");
gets(player1);
fflush(stdin);
printf("Player 2, insert your name (max 10 characters): ");
gets(player2);
for (i = 0; i < DIM; i++) { //Inizialize the grid with '.'
for (j = 0; j < DIM; j++) {
grid[i][j] = '.';
printf("%3c", grid[i][j]);
if (j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
do{
switch (state) {
case 0: //State 0: Player 1 is asked for the coordinates corresponding to the position where you want to insert the X symbol
printf("\n%s your turn: ", player1);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'O') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'X';
c = 'X';
state = 2;
}
else{
state = 0;
printf("Invalid coordinates!\n");
}
break;
case 1: //State 1: Player 2 is asked for the coordinates corresponding to the position where you want to insert the O symbol
printf("\n%s your turn: ", player2);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'X') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'O';
c = 'O';
state = 2;
}
else{
printf("Invalid coordinates!\n");
state = 1;
}
break;
case 2: //State 2: Check if there a right combination of X or O
printf("\n");
for (i = 0; i < DIM; i++) {
for (j = 0; j < DIM; j++) {
printf("%3c", grid[i][j]);
if(j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
nC = 0;
nR = 0;
i = coord[1] - 1;
for (j = 0; j < DIM; j++) {
if(grid[i][j] != c){
break;
}
else{
nR++;
}
}
j = coord[2] - 1;
for (i = 0; i < DIM; i++) {
if (grid[i][j] != c) {
break;
}
else{
nC++;
}
}
if (nC == 3 || nR == 3) state = 3;
else if (c == 'X') state = 1;
else state = 0;
break;
case 3:
if (c == 'X') printf("\n%s IS THE WINNER!\n", player1);
else printf("\n%s IS THE WINNER!\n", player2);
return 0;
break;
}
} while (1);
}
In C, array indices for an array with n elements run from 0 to n−1.
int coord[2] = {0, 0}; defines coord to have two elements, so their indices are 0 and 1.
Throughout the code, coord[1] and coord[2] are used. coord[2] is outside the defined array, so the behavior of the program is not defined by the C standard.

I can't figure why am i getting a segment fault in this dynamic stack

I'm trying to make a board 5x5 and in the middle of this board (that's mean i > 0 and i < 4 ) i want to put a piece in this sub board in randomic way, only 7 theme(if the random number are the same than previous the print have to be the sum of all the pieces above each others).I'm using the dynamic stack for training purpose. I can drew the board exact like i want but i couldn't solve till now de segmentation fault
(EDIT: I already responded this questions with details.)
here is all code;
#include<stdlib.h>
#include<math.h>
#include <stdlib.h>
#include<time.h>
#include <stdbool.h>
typedef struct peca
{
int andares;
int parque;
int teto;
struct peca *prox;
} peca;
typedef struct jogador
{
int andares;
int parque;
int teto;
} jogador;
int aleatorio[101];
main ()
{
jogador norte, sul, leste, oeste;
peca *tabuleiro[5][5];
int por_parque = 0;
srand(time(NULL));
for (int i = 0; i < 101; i++)
{
aleatorio[i] = rand() % 4;
if(i % 2 == 0 && i == 0)
{
aleatorio[i] = aleatorio[i] + 2;
}
else if (i % 2 != 0 && i == 0)
{
aleatorio[i]++;
}
}
printf (" ");
printf (" Norte\n");
for (int i = 0; i < 5; i++)
{
printf (" ");
printf ("+");
for (int j = 0; j < 5; j++)
{
printf ("----");
if (j % 5 == 0);
{
printf ("+");
}
}
printf ("\n");
if (i == 2)
{
printf (" Oeste ");
printf ("|");
}
else
{
printf (" ");
printf ("|");
}
for (int k = 0; k < 5; k++)
{
if ((k > 0 && k < 4) && (i > 0 && i < 4))
{
bool vazio_ou_n = false;
//===========================================================================================
for (int l = 0; l < 100; l++)
{
if (aleatorio[l] == k && aleatorio[l + 1] == i)
{
por_parque++;
vazio_ou_n = true;
break;
}
}
if (vazio_ou_n && por_parque < 7)
{
//============================================================================================
peca * n = malloc(sizeof(peca));
if (n == NULL)
{
printf("erro");
return 1;
}
n->andares++;
if(tabuleiro[i][k] == NULL)
{
tabuleiro[i][k] = n;
n->prox = NULL;
}
else
{
n -> andares = tabuleiro[i][k] -> andares;
n -> andares++;
n -> prox = tabuleiro[i][k];
tabuleiro[i][k] = n;
}
printf(" %d ", tabuleiro[i][k]->andares);
printf ("|");
vazio_ou_n = false;
continue;
}
else if (vazio_ou_n && por_parque == 7)
{
//=====================================================================
peca * n = malloc(sizeof(peca));
n->parque = 1;
if (tabuleiro[i][k] == NULL)
{
tabuleiro[i][k] = n;
}
else
{
por_parque--;
continue;
}
printf("[ %d]", tabuleiro[i][k]->parque);
printf ("|");
vazio_ou_n = false;
continue;
}
}
for (int l = 0; l < 4; l++)
{
printf ("%c", ' '); //"liga" o desenho do tabuleiro a matriz do jogo
}
if (k % 5 == 0);
{
printf ("|");
}
}
//letras do lado direito do tabuleiro
printf (" %c", i + 97);
if (i == 2)
{
printf (" Leste ");
}
printf ("\n");
}
// ultima linh do tabuleiro
printf (" ");
printf ("+");
for (int j = 0; j < 5; j++)
{
printf ("----");
if (j % 5 == 0);
{
printf ("+");
}
}
//numeros de baixo do tabuleiro
printf ("\n");
printf (" ");
for (int j = 0; j < 5; j++)
{
printf (" %d ", j + 1);
if (j % 5 == 0);
{
printf (" ");
}
}
printf ("\n");
printf (" ");
printf (" Sul\n");
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
peca* tmp = NULL;
peca* fre = tabuleiro[i][j];
while (fre != NULL)
{
tmp = fre -> prox;
free(fre);
fre = tmp;
}
}
}
}
the part that that i have been thinking tha were the bug
if (n == NULL)
{
printf("erro");
return 1;
}
n->andares++;
if(tabuleiro[i][k] == NULL)
{
tabuleiro[i][k] = n;
n->prox = NULL;
}
else
{
n -> andares = tabuleiro[i][k] -> andares;
n -> andares++;
n -> prox = tabuleiro[i][k];
tabuleiro[i][k] = n;
} ```
I'm new programing and i still don't know use debugger very well, so if anyone can help, i'm glad
(i%2==0 && i==0)
You're telling the computer: if it's even and is equal to zero.. . See it?
It was a poor code but I believe now it might help someone. Besides the other errors , I'll show them in the code below. The main problem was the segment fault and the way I was dealing with pointers. And it is the main point that I would like to talk about, because this is what will help whoever find this question and also is the answer to this question.
There are two errors exactly regarding the poiterns dealing. The first one is peca *tabuleiro[5][5]; where is the segment fault. In some "intuitive way" while you are coding you may think the once you typed peca *tabuleiro[5][5]; as int type variables, this will be set to NULL automatically as a pattern behavior.
But it points to a random location in memory when you declare it. It could be pointing into the system stack, or the global variables, or into the program's code space, or into the operating system. It should be peca *tabuleiro[5][5] = {{NULL}}; becouse you need to set them for NULL.
And the second error was that for the almost same reason, once you fix the mistake there are some random huge integers instead of what is expected. And this is happening because once was created the new peace peca * n = malloc(sizeof(peca)); the n->andares point to a space in memory but not overlay the integer there. I fix the code and commented what i replace.
#include<stdlib.h>
#include<math.h>
#include <stdio.h>
/*#include<stdlib.h>*/
#include<time.h>
#include <stdbool.h>
typedef struct peca
{
int andares;
int parque;
int teto;
struct peca *prox;
} peca;
typedef struct jogador
{
int andares;
int parque;
int teto;
} jogador;
int aleatorio[101];
int main ()
{
jogador norte, sul, leste, oeste;
/*peca *tabuleiro[5][5];*/
peca *tabuleiro[5][5] = {{NULL}};
int por_parque = 0;
srand(time(NULL));
for (int i = 0; i < 101; i++)
{
aleatorio[i] = rand() % 4;
/*if(i % 2 == 0 && i == 0)*/
if(i % 2 == 0 || i == 0)
{
aleatorio[i] = aleatorio[i] + 2;
}
/*else if (i % 2 != 0 && i == 0)*/
else if (i % 2 != 0 || i == 0)
{
aleatorio[i]++;
}
}
printf (" ");
printf (" Norte\n");
for (int i = 0; i < 5; i++)
{
printf (" ");
printf ("+");
for (int j = 0; j < 5; j++)
{
printf ("----");
if (j % 5 == 0);
{
printf ("+");
}
}
printf ("\n");
if (i == 2)
{
printf (" Oeste ");
printf ("|");
}
else
{
printf (" ");
printf ("|");
}
for (int k = 0; k < 5; k++)
{
if ((k > 0 && k < 4) && (i > 0 && i < 4))
{
bool vazio_ou_n = false;
//===========================================================================================
/*for (int l = 0; l < 100; l++)*/
for (int l = 0; l < 99; l++)
{
if (aleatorio[l] == k && aleatorio[l + 1] == i)
{
por_parque++;
vazio_ou_n = true;
break;
}
}
if (vazio_ou_n && por_parque < 7)
{
//============================================================================================
peca * n = malloc(sizeof(peca));
if (n == NULL)
{
printf("erro");
return 1;
}
n->andares = 1;
n->teto = 0;
n->parque = 0;
n->prox = NULL;
/*n->andares++;*/
if(tabuleiro[i][k] == NULL)
{
tabuleiro[i][k] = n;
n->prox = NULL;
}
else
{
n -> andares = tabuleiro[i][k] -> andares;
n -> andares++;
n -> prox = tabuleiro[i][k];
tabuleiro[i][k] = n;
}
printf(" %d ", tabuleiro[i][k]->andares);
printf ("|");
vazio_ou_n = false;
continue;
}
else if (vazio_ou_n && por_parque == 7)
{
//=====================================================================
peca * n = malloc(sizeof(peca));
n->parque = 1;
if (tabuleiro[i][k] == NULL)
{
tabuleiro[i][k] = n;
}
else
{
por_parque--;
continue;
}
printf("[ %d]", tabuleiro[i][k]->parque);
printf ("|");
vazio_ou_n = false;
continue;
}
}
for (int l = 0; l < 4; l++)
{
printf ("%c", ' '); //"liga" o desenho do tabuleiro a matriz do jogo
}
if (k % 5 == 0);
{
printf ("|");
}
}
//letras do lado direito do tabuleiro
printf (" %c", i + 97);
if (i == 2)
{
printf (" Leste ");
}
printf ("\n");
}
// ultima linh do tabuleiro
printf (" ");
printf ("+");
for (int j = 0; j < 5; j++)
{
printf ("----");
if (j % 5 == 0);
{
printf ("+");
}
}
//numeros de baixo do tabuleiro
printf ("\n");
printf (" ");
for (int j = 0; j < 5; j++)
{
printf (" %d ", j + 1);
if (j % 5 == 0);
{
printf (" ");
}
}
printf ("\n");
printf (" ");
printf (" Sul\n");
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
peca* tmp = NULL;
peca* fre = tabuleiro[i][j];
while (fre != NULL)
{
tmp = fre -> prox;
free(fre);
fre = tmp;
}
}
}
return 0;
}
I redone this project and proposed a mathematical way to solve the proposed main problem. Hope that it was helpfull.

Malloc won't sort more than 8 inputs

My program takes 3 lines of input. The first line being whether you want to sort it by odd or even, the second line being how large your array is and the third line being the integers in the array. It works until you use an array larger than 8. I believe it's to do with malloc but I've tried to debug this code for a couple of hours now and I can't fix this issue.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* sort;
int n;
int* ar;
int i;
int test()
{
int temp;
int j = 1;
//printf("%s", sort);
if (strcmp(sort, "odd") == 0) {
for (i = 0; i < n;) {
if (j != n) {
if (ar[i] % 2 != 0) {
if (ar[j] % 2 != 0) {
if (ar[j] < ar[i]) {
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
j++;
}
else {
j++;
}
}
else {
j++;
}
}
else {
j++;
i++;
}
}
else {
i++;
j = i + 1;
}
}
}
if (strcmp(sort, "even") == 0) {
for (i = 0; i < n; i++) {
if (j != n) {
if (ar[i] % 2 == 0) {
if (ar[j] % 2 == 0) {
if (ar[j] < ar[i]) {
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
j++;
}
else {
j++;
}
}
else {
j++;
}
}
else {
j++;
i++;
}
}
else {
i++;
j = i + 1;
}
}
}
}
void main()
{
ar = malloc(sizeof(int) * n);
sort = malloc(sizeof(char) + 1);
printf("Enter odd or even\n");
scanf("%s", sort);
// printf("please input odd or even\n");
printf("Enter the size of the array \n");
scanf("%d", &n);
//printf("%s", sort);
printf("Enter the elements of the array \n");
for (i = 0; i < n; i++) {
scanf("%d", &ar[i]);
}
test();
for (i = 0; i < n; i++) {
printf("%d ", ar[i]);
}
// return 0;
}
Code is typically executed in a linear fashion, but you don't seem to be doing that. You're allocating ar using n, but don't have a value for n yet until several lines later...
ar = malloc(sizeof(int) * n);
sort = malloc(sizeof(char) + 1);
printf("Enter odd or even\n");
scanf("%s", sort);
// printf("please input odd or even\n");
printf("Enter the size of the array \n");
scanf("%d", &n);
You're also not allocating the size of sort big enough to contain any string longer than 1 character.

Number Board Program doesn't place hyphens correctly in C

We're supposed to create a number board whereby a user is allowed to select a number for instance, number 5 and one of the number 5's in the board will be clearly indicated as selected with a hyphen above and below it.
Problem now is: No matter what I try the hyphens refuse to move to the right spot.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define HEIGHT 9
#define WIDTH 8
void board(char array[HEIGHT][WIDTH])
{
int x,y,i,j,score,steps = 0;
/****BORDER CREATION*/
for (i = 0; i < WIDTH+4; i ++)
printf("# ");
printf("\n");
for(y=0;y<WIDTH+1;y++)
{
printf("\n");
printf("# ");
for(x=0;x<HEIGHT+1;x++)
{
printf("%c ",array[y][x]);
}
printf("# ");
printf("\n\n");
}
for (i = 0; i < WIDTH+4; i ++)
printf("# ");
printf("\n");
/****BORDER CREATION*/
}
void instruc(char *name, int *steps, int *selected)
{
/*User record & score header*/
printf("\n-----Hello %s! Let's see what you can do------\n",name);
printf("----------WELCOME TO NUMBER CONNECT----------\n");
printf("----------PREVIOUS PLAYERS' RECORDS----------\n");
printf("----------Name: %s Score(Steps): %i--\n\n",name,*steps);
printf("\nYour score: %i",*steps);
printf("\nNumber %i is currently selected",*selected);
printf("\n\nAction Keys: ");
printf("\nPush 'U' to move UP");
printf("\nPush 'D' to move DOWN");
printf("\nPush 'L' to move LEFT");
printf("\nPush 'R' to move RIGHT");
printf("\nPush 'X' to REMOVE path\n");
printf("\nTo select a new number, press digits from 1 to 7\n");
printf("\nPush 'q' or 'Q' to QUIT\n\n");
}
void select(int *selected,char array[HEIGHT][WIDTH])
{
int i,j,x;
printf("\nPlease select a number (1-8): ");
fflush(stdin);
scanf("%i",selected);
/*POINTER TYPE CONVERTION FAIL
selected = (char)*selected;*/
/*ASCII CHARACTER ATTEMPT FAIL
if (*selected == 1){
*selected = 1;
}
else if (*selected == 2){
*selected = 2;}
else if (*selected == 3){
*selected = 3;}
else if (*selected == 52){
*selected = 4;}
else if (*selected == 53){
*selected = 5;}
else if (*selected == 54){
*selected = 6;}
else if (*selected == 55){
*selected = 7;}
else if (*selected == 56){
*selected = 8;}
else{
printf("Non-Numeric Input not allowed");}*/
printf("\nNumber Selected: %i",*selected);
/*To indicate selected number with hyphens (denoted by 45)*/
for (i = 0; i < WIDTH+1;i++)
{
for (j =0; j < HEIGHT+1; j++){
if (array[i][j] == *selected){
array[i-1][j] = 45;
array[i+1][j] = 45;
}
}
}
printf("\nPosition of i: %i ",i);
printf("Position of j: %i\n\n",j);
}
void assign(char array[HEIGHT][WIDTH], int *selected)
{
int i,j;
/*int rr,rrr;
int x = 0;
srand((unsigned) time(NULL));
for (i = 0; i < WIDTH+3;i++)
{
for (j = 0; j < HEIGHT; j++){
x = (rand()%8+1)+48;
array[i][j] = x;
}
}
for (i = 0; i < WIDTH+3;i++)
{
for (j = 0; j < HEIGHT+3; j++){
rr = rand()%WIDTH;
rrr = rand()%HEIGHT;
x= 32;
array[rr][rrr] = x;
}
}
printf("\n");*/
/*To blank our everything that is not a symbol*/
array[0][1] = 49;
array[0][7] = 49;
array[5][9] = 50;
array[6][1] = 50;
array[1][4] = 51;
array[5][7] = 51;
array[7][2] = 52;
array[5][5] = 52;
array[3][3] = 53;
array[1][1] = 53;
array[7][3] = 54;
array[6][2] = 54;
array[3][7] = 55;
array[7][6] = 55;
array[2][4] = 56;
array[4][4] = 56;
for (i = 0; i < WIDTH+4;i++)
{
for (j = 0; j < HEIGHT+4; j++){
if ((array[i][j] != 49) && (array[i][j] != 50) && (array[i][j] != 51) &&
(array[i][j] != 52) && (array[i][j] != 53) && (array[i][j] != 54) && (array[i][j] != 55) &&
(array[i][j] != 56)){
array[i][j] = 32;
}
}
}
}
int main(void)
{
int i,j,x,y,score = 0,steps = 0,result = 0,selected=0;
char array[HEIGHT][WIDTH],name[20];
printf("Please Input Name: ");
scanf("%s",&name);
instruc(name,&steps,&selected);
assign(array,&selected);
board(array);
select(&selected,array);
board(array);
return 0;
}

MiniMax algorithm tic-tac-toe in C explanation

trying to learn about computer game players to familiarise myself with AI. I understand how minimax works in theory but cant get my head around how this code I found online works.
can someone explain the minimax fruction/computer move function (lines 38-78)to me.
credit: https://gist.github.com/MatthewSteel/3158579
thanks
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int minimax(int board[9], int player) {
//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;
move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
Here is the essence of minimax:
int minimax(int board[9], int player) {
// ....
for(i = 0; i < 9; ++i) { //For all moves,
// ....
int thisScore = -minimax(board, player*-1);
}
}
Go through each possible move, and for each such possible move, turn the board around, pretend to be the other player (that's the player*-1 part), and try each possible move. thisScore is set to the negative return value from the recursive call to minimax, since good for the other player equals bad for ourselves.
computerMove just goes through all the possible moves, calls minimax for each such possible move, and uses the one with the best result.

Resources