asder

Connect 4 game με C πρόβλημα με pointers

Recommended Posts

καλυσπέρα φτιάχνω ένα παιχνίδι connect4 (4 στην σειρα) και εχω καποια προβλήματα στους αλγορίθμους για την κίνηση του υπολογιστή. Ο υπολογιστής παίζει με minmax όμως δεν βλέπω να πολύ δουλεύει στο debugging sto dev c++ οταν καλώ τις συναρτήσεις place/rmc/minmax μερικες φορές λέει ότι θέλει pointers η το αντίοστροφο ενώ δίνω απλά μεταβλητές.Παραθέτω τον κώδικα(έχει πολλά αχρείαστα printf μέσα στις ai και minmax συναρτησεις που τα έβαλα γι ανα δω τι γίνεται σβήστε τα αν ενοχλόυν).

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define R 7
#define C 7

int turn=0;
char game_board[R][C]={};
int column_fill[C]={};

void print_table();
void set_table();
void set_column_fill();
void print_table_fill();

void human_plays(int player);
void comp_plays();
int draw(int column_fill[C]);
int win(char board[R][C]);

int place(char (*board)[C] , int *column_fill , int col, int player);
void rmv(char (*board)[C] , int *column_fill , int col);

int minimax(char board[R][C],int column_fill, int depth, int player /*1:player or 2:com*/);
int heuristic(char board[R][C]);
int ai(char board[R][C],int column_fill[C], int depth);



/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
	int draw_val=0,win_val=0;

	
	printf("Player: +    Com: *\n\n");
	
	set_table();
  	set_column_fill();
	//print_table_fill();
	print_table();
	turn++;
	
	printf("\n ~Start~\n");
	
	while ( draw_val!=1 ){
		
		if (turn%2==1){
			printf("Player's' turn\n");
			human_plays(1);		
			win_val = win(game_board);
			if (win_val){
				printf("\n\nCongratulations, you Won!!!\n");
				print_table();
				break;
			}	
			
		}
		else{
			printf("\nCom turn\n");
			comp_plays();
			win_val = win(game_board);
			if (win_val){
				printf("\n\nYou have lost!!! :(");
				printf("\n");
				print_table();
				break;
			}
		}
		
		printf("\n");
		print_table();

		
		turn++;
		draw_val=draw(column_fill);
		
	}
	
	
	
	return 0;
}


void set_table(){
	int row,col;
	
	
	for (row=0;row<R;row++){
		for (col=0;col<C;col++){
			game_board[row][col] = '-';
		}
		
	}
}

void set_column_fill(){
	int col;

	for (col=0;col<C;col++){
		column_fill[col] = R;
	}
}


void print_table(){
	int row,col;
	
	printf("   turn: %d\n",turn);
	
	for (row=0;row<R;row++){
		for (col=0;col<C;col++){
			printf("%c ",game_board[row][col]);
		}
		printf("\n");
		
	}
}

void print_table_fill(){
	int col;

		for (col=0;col<C;col++){
			printf(" %d",column_fill[col]);
		}
		printf("\n");
		
}



void human_plays(int player){
	int user_input, row;

	//Handle two players from the same function
	char choice='+';
	if (player != 1 ) choice = '*';
	
	//Ask user for input
	printf("Enter a column(1-%d):",C);
	scanf("%d",&user_input);

	//Check if column exists
	while ( user_input < 1 || user_input > 7 ){
		printf("Enter a corrent column number:");
		scanf("%d",&user_input);
	}
	//Chsck if column is filled
	while ( column_fill[user_input-1] == 0 ){
		printf("Column is filled, enter again:\n");
		scanf("%d",&user_input);
	}
	//Do some magic!
	user_input--;
	place(game_board , column_fill ,user_input,player);
	
	//Print something...
	printf("\nPlayer places at row %d",user_input+1);
}

void comp_plays(){
	
//	char cpu_mind[R][C]; //It's all in the mind...
//	int cpu_column_fill[C];
	int answer;
	
//	int row,col;
//	for (row=0 ; row < R ; row++){
//		for( col=0 ; col < C ; col++){
//		cpu_mind[row][col]= game_board[row][col];
//		}
//	}
//	
//	for( col=0 ; col < C ; col++){
//		cpu_column_fill[col] =column_fill[col];
//		}
	
	answer = ai( game_board ,column_fill,5);
	place(game_board,column_fill,answer,2);
	printf("Com places at :%d",answer);
	
}



int draw(int column_fill[C]){
	int col;
	
	for (col=0 ; col<C ; col++){
		if (column_fill[col] !=0) return 0;
		}
	return 1;
}

int win(char board[R][C]){
	int row , col;
	char mark;
	
	//Check Horizontal
	for (row=0 ; row < R ; row++){
		for( col=0 ; col < C-3 ; col++){
			//mark = board[row][col];
			if (board[row][col] == '-') continue;  //pass if scan find "-" to avoid win result on empty cells
		
			if (board[row][col+1] == board[row][col] && board[row][col+2]== board[row][col] && board[row][col+3] == board[row][col] ){
				if (board[row][col] == '+') return 1;
				else return 2;
			}
		}
	}
	
	//Check Verical
	for (row=0 ; row < R-3 ; row++){
		for( col=0 ; col < C ; col++){
			mark = board[row][col];
			if (mark == '-') continue;
			if (board[row+1][col] == mark && board[row+2][col]== mark && board[row+3][col] == mark ){
				if (mark == '+') return 1;
				else return 2;	
			}
		}
	}
	 
	 
	//Check  linear (/)
	for (row=0 ; row < R - 3 ; row++){
		for (col=0 ; col < C - 3 ; col ++){
		mark = board[row][col];
		if (mark == '-') continue; 
		if (board[row+1][col+1] == mark && board[row+2][col+2]== mark && board[row+3][col+3] == mark ){
				if (mark == '+') return 1;
				else return 2;
			}
		}
	}
	
	
	//Check  other linear (\)
	for (row=0 ; row < R-3 ; row++){
		for (col=3 ; col < C ; col ++){
		mark = board[row][col];
		if (mark == '-') continue; 
		if (board[row+1][col-1] == mark && board[row+2][col-2]== mark && board[row+3][col-3] == mark ){
				if (mark == '+') return 1;
				else return 2;
			}
		}
	}
	
	return 0;
}


int place(char (*board)[C] , int *column_fill , int col, int player){
	
	int row = --column_fill[col];
	
	board[row][col] =  (player==1 ) ?  '+' :  '*';
	
	return 0;
}

void rmv(char (*board)[C] , int *column_fill , int col){
	
	int row = column_fill[col]++;
	board[row][col]= '-';
	
}


int heuristic(char board[R][C]) {
	int result = 0;
	int row, col;

	char mark;
	
	//Check Horizontal
	for (row=0 ; row < R ; row++){
		for( col=0 ; col < C-3 ; col++){
			mark = board[row][col];
			if (mark == '-') continue;  //pass if scan find "-" to avoid win result on empty cells
		
			if (board[row][col+1] == mark && board[row][col+2]== mark && board[row][col+3] == mark ){
				if (mark == '+') result-- ;
				else result++;
			}
		}
	}
	
	//Check Verical
	for (row=0 ; row < R - 3 ; row++){
		for( col=0 ; col < C ; col++){
			mark = board[row][col];
			if (mark == '-') continue;
			if (board[row+1][col] == mark && board[row+2][col]== mark && board[row+3][col] == mark ){
				if (mark == '+') result--;
				else result++;	
			}
		}
	}
	return result;
}

int minimax(char board[R][C],int column_fill, int depth, int player /*1:player or 2:com*/){
	int win_val;
	int col, best;
	int n=-10000-1;
	
	printf("board %c ",board[0][0]);
	
	win_val =draw(column_fill);
	if (win_val) return 0; //draw 
	
	//printf("col fill \n\n\n\n\%d" ,column_fill[1]);
	
	win_val = win(board);
	if (win_val){
		if (win_val == player) return 10000 ;
		else return -10000;
	}
	
	if(depth==0)
		return ((player==1) ? heuristic(board) : -heuristic(board));
		
	best = -10000;
	
	
	for(col=0; col<C; col++){ //check every move
		printf("minmax: %d",col);
		if(board[0][col]=='-') { //make sure coloumn isn't empty
			//put(board, row, turn);
			place(board ,column_fill , col, player);
			n = minimax(board,column_fill, depth-1, 3-player);
			if(player==1) {
				if(-n>best) best = -n;
			} else { //player==2
				if(-n>best) best = -n;
			}
			//rmv(s, i);
			rmv(board ,column_fill , col);
		}
		printf("best: %d\n",best);
	}

	return best;
}

int ai(char board[R][C],int column_fill[C], int depth) {
	int col, move;
	int n; 
	int val =-10000-1;
	move = -2;//debug
	
	printf("n\n\%c\n\n",board[0][0]);

	for(col=0; col<C; col++){
		printf("ai: %d",col);
		if(board[0][col]=='-') {
			//put(s, i, 2);
			place(board,column_fill, col,2);
			n = minimax(board,column_fill, depth, 2);
			printf("\n n: %d",n);
			if(-n>val) {
				val = -n;
				move = col;
			}
			rmv(board,column_fill, col);
		}
	}
	printf("\n\n %d \n",move);

	return move;
}

 

Link to comment
Share on other sites

Στον ορισμό της minmax (και στην υλοποίηση):

int minimax(char board[R][C], int column_fill, int depth, int player);

το column_fill πρέπει να περνιέται σαν Pointer αφού είναι πίνακας.

  • Like 2
Link to comment
Share on other sites

39 minutes ago, klapeto said:

Στον ορισμό της minmax (και στην υλοποίηση):


int minimax(char board[R][C], int column_fill, int depth, int player);

το column_fill πρέπει να περνιέται σαν Pointer αφού είναι πίνακας.

Είσαι θεός είχα ξεχάσει να βάλω τις αγγηλες...τοσες ώρες 

τωρα μένει να καταλάβω γιατί ο minmax ειναι λιγό χαζός....:gizmo:

Edited by asder
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now