1. 程式人生 > >自定義棋盤大小的N子棋

自定義棋盤大小的N子棋

三子棋程式碼:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

//對於陣列的長度,最好定義成巨集
//方便程式的擴充套件,改巨集定義則可修改陣列元素個數
#define ROW 3
#define COL 3

//1.定義二維陣列來表示棋盤
char g_chess_board[ROW][COL];

void Init(){
	//初始化棋盤
	for (int row = 0; row < ROW; ++row){
		for (int col = 0; col < COL; ++col){
			g_chess_board[row][col] = ' ';
		}
	}
}

void Print(){
	//列印
	for (int row = 0; row < ROW; row++){
		printf("| %c | %c | %c |\n", g_chess_board[row][0],
			g_chess_board[row][1], g_chess_board[row][2]);
		if (row != ROW - 1){
			printf("|---|---|---|\n");
		}
	}
}

void PlayMove(){
	//玩家落子
	while (1){
		//1.提示玩家輸入一個座標
		printf("請玩家落子(輸入座標row col):\n");
		//2.讀取玩家的輸入
		int row = -1;
		int col = -1;
		scanf("%d %d", &row, &col);
		//3.對玩家的輸入進行校驗
		//4.若輸入非法,迴圈提示使用者重新輸入
		//   a.校驗座標是否範圍合理
		if (row < 0 || row >= ROW || col < 0 || col >= COL){
			printf("輸入的座標非法,請重新輸入!\n");
			continue;
		}
		//   b.玩家輸入的座標對應位置是否已經有子
		if (g_chess_board[row][col] != ' '){
			//當前位置已被佔用,不可落子
			printf("當前位置已經有子了,請重新輸入!\n");
			continue;
		}
		//5.若輸入合法,則把對應位置設為'x'
		g_chess_board[row][col] = 'x';
		break;
	}
}

void ComputerMove(){
	//電腦落子
	//1.隨機數產生行和列
	//2.若當前位置被佔用,則再產生一次
	printf("請電腦落子!\n");
	int row = 0;
	int col = 0;
	while (1){
		row = rand( ) % ROW;   //[0,2]
		col = rand( ) % COL;   //[0,2]
		if (g_chess_board[row][col] == ' '){
			g_chess_board[row][col] = 'o';	
			break;
		}	
	}
}

int IsFull(){
	for (int row = 0; row < ROW; ++row){
		for (int col = 0; col < COL; ++col){
			if (g_chess_board[row][col] == ' '){
				return 0;
			}
		}
	}
	return 1;
}

//x 表示玩家,o 表示電腦
//返回 x 表示玩家勝利,返回 o 則電腦勝利
//返回 q 表示和棋
//返回 空格 則勝負未分
char CheckWinner(){
	//檢測遊戲是否結束
	//1.先檢查所有行是否連在一起
	for (int row = 0; row < ROW; ++row){
		if (g_chess_board[row][0] == g_chess_board[row][1]
			&& g_chess_board[row][0] == g_chess_board[row][2]
			&&g_chess_board[row][0] !=' '){
			return g_chess_board[row][0];
		}
	}
	//2.在檢查所有列是否連在一起
	for (int col = 0; col < COL; ++col){
		if (g_chess_board[0][col] == g_chess_board[1][col]
			&& g_chess_board[0][col] == g_chess_board[2][col]
			&& g_chess_board[0][col] !=' '){
			return g_chess_board[0][col];
		}
	}

	//3.檢查對角線
	if (g_chess_board[0][0] == g_chess_board[1][1]
		&& g_chess_board[0][0] == g_chess_board[2][2]
		&& g_chess_board[0][0] != ' '){
		return g_chess_board[0][0];
	}
	if (g_chess_board[2][0] == g_chess_board[1][1]
		&& g_chess_board[2][0] == g_chess_board[0][2]
		&& g_chess_board[2][0] != ' '){
		return g_chess_board[2][0];
	}
	//4.檢查是否和棋
	if (IsFull()){
		return 'q';
	}
	return ' ';
}

int main(){
	//1.對其盤進行初始化(全是空格)
	char winner = ' ';
	Init();
	while (1){
        //2.列印棋盤
		Print();
	//3.玩家落子,檢查遊戲是否結束
		PlayMove();
		winner = CheckWinner();
		if (winner != ' '){
			//遊戲結束
			break;
		}
	//4.電腦落子,檢查遊戲是否結束
		ComputerMove();
		winner = CheckWinner();
		if (winner != ' '){
			//遊戲結束
			break;
		}
	}
	if (winner == 'x'){
		printf("玩家獲勝!\n");
	}
	else if (winner == 'o'){
		printf("電腦獲勝\n");
	}
	else if (winner == 'q'){
		printf("和棋\n");
	}
	system("pause");
	return 0;
}

為了使程式具有通用性,現將程式碼改進。在使用時,只需將下列程式碼中巨集的N改為所想要的數字,即可實現N子棋。

自定義棋盤大小的N子棋程式碼:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define CHESS_ROW 5
#define CHESS_COL 5
#define ROW 3
#define COL 3

//定義全域性變數
char g_chessboard[CHESS_ROW][CHESS_COL];

void Initialize(){
	//初始化棋盤
	int row;
	int col;
	for (row = 0; row < CHESS_ROW; row++){
		for (col = 0; col < CHESS_COL; col++){
			g_chessboard[row][col] = ' ';
		}
	}
}

void Print(){
	//列印棋盤
	int row;
	int col;
	//列印列數
	printf("   ");
	for (col = 0; col < CHESS_COL; col++){
		printf("   %d ", col);
	}
	printf("\n");

	for (row = 0; row < CHESS_ROW; row++){
		//列印行號
		printf("%02d  ", row);
		for (col = 0; col < CHESS_COL; col++){
			printf("| %c  ", g_chessboard[row][col]);
		}
		printf("|\n");
		printf("    ");
		if (row != CHESS_ROW - 1){
			for (col = 0; col < CHESS_COL; col++){
				printf("|----");
			}
			printf("|\n");
		}
	}
}

void Player(){
	//玩家落子
	while (1){
		int row;
		int col;
		printf("\n請輸入落子位置(row col):\n");
		scanf("%d %d", &row, &col);
		if (row >= CHESS_ROW || row<0 || col >= CHESS_COL || col < 0){
			printf("您的輸入有誤,請重新輸入\n");
			continue;
		}
		if (g_chessboard[row][col] != ' '){
			printf("此位置已被佔有,請重新輸入\n");
			continue;
		}
		g_chessboard[row][col] = 'x';
		break;
	}
}

void Computer(){
	printf("電腦落子:\n");
	int row = 0;
	int col = 0;
	srand(time(0));
	while (1){
		row = rand() % CHESS_ROW;
		col = rand() % CHESS_COL;
		//若位置沒有被佔用,落子
		if (g_chessboard[row][col] == ' '){
			g_chessboard[row][col] = 'o';
			break;
		}
	}
}

int IsFull(){
	for (int row = 0; row < CHESS_ROW; row++){
		for (int col = 0; col < CHESS_COL; col++){
			if (g_chessboard[row][col] == ' '){
				return 0;
			}
		}
	}
	return 1;
}

char Check(){
	//檢查行
	for (int row = 0; row < CHESS_ROW; row++){
		int countp = 0;
		int countc = 0;
		for (int col = 0; col < CHESS_COL; col++){
			if (g_chessboard[row][col] == 'x'){
				countp++;
			}
			else if (g_chessboard[row][col] == 'o'){
				countc++;
			}
			else if (g_chessboard[row][col] == ' '){
				countc = countp=0;
			}
		}
		if (countp == ROW){
			return 'x';
			break;
		}
		else if (countc == ROW){
			return  'o';
			break;
		}
	}
	//檢查列
	for (int col = 0; col < CHESS_COL; col++){
		int countp = 0;
		int countc = 0;
		for (int row = 0; row < CHESS_ROW; row++){
			if (g_chessboard[row][col] == 'x'){
				countp++;
			}
			else if (g_chessboard[row][col] == 'o'){
				countc++;
			}
			else if (g_chessboard[row][col] == ' '){
				countc = countp = 0;
			}
		}
		if (countp == COL){
			return  'x';
			break;
		}
		else if (countc == COL){
			return 'o';
			break;
		}
	}
	//檢查對角線
	int row = 0;
	int col = 0;
	int countp = 0;
	int countc = 0;
	//左上角開始的對角線
	while (row < CHESS_ROW){
		if (g_chessboard[row][col] == 'x'){
			countp++;
		}
		else if (g_chessboard[row][col] == 'o'){
			countc++;
		}
		else if (g_chessboard[row][col] == ' '){
			countc = countp = 0;
		}
		row++;
		col++;
		if (countp == ROW){
			return 'x';
			break;
		}
		else if (countc == ROW){
			return 'o';
			break;
		}
	}
	//右上角開始的對角線
	countp = 0;
	countc = 0;
	row = 0;
	col = CHESS_COL- 1;
	while (row<CHESS_ROW){
		if (g_chessboard[row][col] == 'x'){
			countp++;
		}
		else if (g_chessboard[row][col] == 'o'){
			countc++;
		}
		else if (g_chessboard[row][col] == ' '){
			countc = countp = 0;
		}
		row++;
		col--;
		if (countp == ROW){
			return 'x';
			break;
		}
		else if (countc == ROW){
			return 'o'; 
			break;
		}
	}

	//檢查棋盤是否已滿
	if (IsFull()){
		return 'q';
	}
	return ' ';
}

int main(){
	//1.棋盤初始化
	char winner = ' ';
	Initialize();
	while (1){
		//2.列印棋盤
		Print();
		//3.玩家落子,進行檢驗
		Player();
		winner = Check();
		//遊戲結束
		if (winner != ' '){
			Print();
			break;
		}
		//4.電腦落子,進行檢驗
		Computer();
		winner = Check();
		//遊戲結束
		if (winner != ' '){
			Print();
			break;
		}
	}
	//5.判斷勝負
	//用 x 代表玩家,o 代表電腦,q代表和棋
	if (winner == 'x'){
		printf("恭喜你獲勝!\n");
	}
	else if (winner == 'o'){
		printf("啊哦,電腦獲勝!\n");
	}
	else if (winner == 'q'){
		printf("和棋\n");
	}
	system("pause");
	return 0;
}