I am in an adventure trying to test my C language programming skills and I am re-developing a simple game code based on the board game called REVERSI. I want the game to be between the user/player playing against an Artificial Inteligence player and I want to make it possible to undo both the player's and AI player moves in the board. Struggling to develop the code for this (using linked structures and dynamic memory).
I tried to write those but I am not getting it right. The undo function is not working at all. One way I thought about is to display an updated board after both players possible valid moves, and the actual move made(in the case of the AI player for better testing) but I can not get it to undo the main player's and the AI player's moves.
Below I have provided my code with what I have managed to do until now:
#define VAZIO '.'
#define PRETO 'X'
#define BRANCO 'O'
#define JOGADA_VALIDA '#'
#define SIZE_TABULEIRO 8
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
/**********************************************************************************/
/* Inicializa o tabuleiro com as peças nas posições iniciais */
void inicializa_tabuleiro(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO])
{
int i, j;
for (i = 0; i < SIZE_TABULEIRO; i++)
{
for (j = 0; j < SIZE_TABULEIRO; j++)
{
tabuleiro[i][j] = VAZIO;
}
}
tabuleiro[3][3] = BRANCO;
tabuleiro[4][4] = BRANCO;
tabuleiro[3][4] = PRETO;
tabuleiro[4][3] = PRETO;
}
/***********************************************************************************/
/* Exibe o tabuleiro com as coordenadas de 0-7 em cima e na esquerda */
void mostra_tabuleiro(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO])
{
int i;
printf(" ");
/* Imprime as coordenadas na linha superior */
for (i = 0; i < SIZE_TABULEIRO; i++)
{
printf("%d ", i);
}
printf("\n");
/* Imprime as peças e as coordenadas nas demais linhas */
for (i = 0; i < SIZE_TABULEIRO; i++)
{
printf("%d ", i);
printf("\n");
}
}
/***********************************************************************************************/
int movimento_valido(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO], int linha, int coluna, char jogador)
{
int i, j, x, y, tem_oponente;
int oponente = (jogador == PRETO) ? BRANCO : PRETO;
/* Verifica se a célula está vazia */
if (tabuleiro[linha][coluna] != VAZIO) {
return 0;
}
/* Verifica em todas as direções se há peças do oponente que podem ser capturadas */
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
/* Ignora a própria posição e verifica apenas as direções */
if (i == 0 && j == 0) {
continue;
}
x = linha + i;
y = coluna + j;
tem_oponente = 0;
while (x >= 0 && x < SIZE_TABULEIRO && y >= 0 && y < SIZE_TABULEIRO && tabuleiro[x][y] == oponente) {
x += i;
y += j;
tem_oponente = 1;
}
if (tem_oponente && x >= 0 && x < SIZE_TABULEIRO && y >= 0 && y < SIZE_TABULEIRO && tabuleiro[x][y] == jogador) {
return 1;
}
}
}
return 0;
}
/************************************************************************************************/
void marca_movimentos_validos(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO], char jogador)
{
int i, j;
for (i = 0; i < SIZE_TABULEIRO; i++)
{
for (j = 0; j < SIZE_TABULEIRO; j++)
{
if (tabuleiro[i][j] == VAZIO && movimento_valido(tabuleiro, i, j, jogador))
{
tabuleiro[i][j] = JOGADA_VALIDA;
}
}
}
}
/*************************************************************************************************/
void mostra_tabuleiro_com_movimentos_validos(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO], char jogador)
{
int i, j;
marca_movimentos_validos(tabuleiro, jogador);
printf(" ");
/* Imprime as coordenadas na linha superior */
for (i = 0; i < SIZE_TABULEIRO; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 0; i < SIZE_TABULEIRO; i++)
{
printf("%d ", i);
for (j = 0; j < SIZE_TABULEIRO; j++)
{
switch (tabuleiro[i][j])
{
case VAZIO:
printf(". ");
break;
case PRETO:
printf("X ");
break;
case BRANCO:
printf("O ");
break;
case JOGADA_VALIDA:
printf("# ");
break;
}
}
printf("\n");
}
}
/*************************************************************************************************/
void jogada(int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO], char jogador) {
int linha, coluna, i, j, x, y, oponente, tem_oponente;
/* Marca as jogadas válidas no tabuleiro */
marca_movimentos_validos(tabuleiro, jogador);
while (true) {
/* Solicita as coordenadas da jogada ao jogador */
printf("\nJogador %c, insira a linha e a coluna da sua jogada separadas por um espaco: ", jogador);
if (scanf("%d %d", &linha, &coluna) != 2) {
printf("Coordenadas invalidas. Tente novamente.\n");
/* Limpa o buffer do scanf no caso de entrada inválida */
while (getchar() != '\n') {}
continue;
}
/* Verifica se as coordenadas da jogada são válidas */
if (linha < 0 || linha >= SIZE_TABULEIRO || coluna < 0 || coluna >= SIZE_TABULEIRO) {
printf("Coordenadas invalidas. Tente novamente.\n");
continue;
}
if (tabuleiro[linha][coluna] != JOGADA_VALIDA) {
printf("Jogada invalida. Tente novamente.\n");
continue;
}
/* Executa a jogada no tabuleiro */
tabuleiro[linha][coluna] = jogador;
oponente = (jogador == PRETO) ? BRANCO : PRETO;
/* Verifica em todas as direções se há peças do oponente que podem ser capturadas */
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
/* Ignora a própria posição e verifica apenas as direções */
if (i == 0 && j == 0) {
continue;
}
x = linha + i;
y = coluna + j;
tem_oponente = 0;
while (x >= 0 && x < SIZE_TABULEIRO && y >= 0 && y < SIZE_TABULEIRO && tabuleiro[x][y] == oponente) {
x += i;
y += j;
tem_oponente = 1;
}
if (tem_oponente && x >= 0 && x < SIZE_TABULEIRO && y >= 0 && y < SIZE_TABULEIRO && tabuleiro[x][y] == jogador) {
/* Gira as peças do oponente */
x -= i;
y -= j;
while (tabuleiro[x][y] == oponente) {
tabuleiro[x][y] = jogador;
x -= i;
y -= j;
}
}
}
}
/* Troca a vez para o oponente */
jogador = oponente;
/* Mostra o tabuleiro atualizado */
mostra_tabuleiro_com_movimentos_validos(tabuleiro, jogador);
}
/* Mostra o tabuleiro final */
mostra_tabuleiro_com_movimentos_validos(tabuleiro, jogador);
printf("Jogadas validas marcadas com '#' \n");
}
/************************************************************************************************/
int main()
{
char jogador;
int tabuleiro[SIZE_TABULEIRO][SIZE_TABULEIRO];
printf("Bem vindo ao jogo Reversi :) \n");
printf("Escolha uma peca para jogar: X ou O? \n");
scanf(" %c", &jogador);
printf("\n");
while(jogador != 'X' && jogador != 'O')
{
printf("Peca invalida. Escolha novamente: X ou O? \n");
scanf(" %c", &jogador);
}
/* Inicializa o tabuleiro */
inicializa_tabuleiro(tabuleiro);
mostra_tabuleiro_com_movimentos_validos(tabuleiro, jogador);
printf("\n");
printf("Jogadas validas estao marcadas com '#' \n");
jogada(tabuleiro, jogador); /* ou jogada(tabuleiro, BRANCO); */
return 0;
}