游戏规则

黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

三子棋 python 三子棋图片_#define

算法设计

  • 首先我们需要设计一个游戏开始菜单,整个逻辑我们可以使用do while嵌套switch语句完成。(test.c)
  • 其次要进行游戏设计(我们创建函数的声明game.h和函数实现game.c两个文件):
  • 首先设计对棋盘初始化的函数,因为该棋盘为二维,所以我们应该创建二维数组来进行存储。
  • 其次应该设计棋盘的显示效果函数,将该二维数组按照一定格式输出。
  • 然后就是分别控制玩家和电脑下棋的函数,按照一定的规则即可。
  • 再然后就需要进行胜负的判定,有很多种不同的情况。
  • 最后则是游戏逻辑函数的实现,调用以上功能函数实现游戏整体效果。

代码实现介绍

game.h

其中包含了各个函数的声明,以及各个指标的宏定义。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define DRAW 'd' //平局
#define CONTINUE 'c' //继续下棋
#define COMPUTER 'O' //电脑下棋
#define PLAYER 'X' //玩家下棋
#define BLANK ' ' //BLANK为空格字符用于初始化棋盘数组
#define ROW 3 //行
#define COL 3 //列

void tic_tac_toe(); //游戏逻辑函数
void init_board(char arr[ROW][COL]); //棋盘初始化函数
void show_board(char arr[ROW][COL]); //显示效果函数
char judge_game(char arr[ROW][COL]); //胜负判定函数
void player(char arr[ROW][COL]); //玩家下棋函数
void computer(char arr[ROW][COL]); //电脑下棋函数

game.c

其中包含了各个函数的具体实现。

棋盘初始化函数

函数逻辑:

  • 将二维数组进行遍历,并将其都赋值为设定的初值。

代码实现:

void init_board(char arr[ROW][COL]) {
	int i;
	int j;
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < COL; j++) {
			arr[i][j] = BLANK;
		}
	}
}
显示效果函数

函数逻辑:

  • 首先我们应该输出棋盘的坐标(行和列)
  • 然后需要将棋盘展现出来,就要在输出数字的同时将棋盘边界输出。

三子棋 python 三子棋图片_开发语言_02

代码实现:

void show_board(char arr[ROW][COL]) {
	int i;
	int j;
	for (i = 0; i <= ROW; i++) {
		printf(" %d  ", i);
	}
	printf("\n   -------------\n");
	for (i = 0; i < ROW; i++) {
		printf(" %d ", i + 1);
		for (j = 0; j < COL; j++) {
			if (j == 1) {
				printf(" %c ", arr[i][j]);
			}
			else {
				printf("| %c |", arr[i][j]);
			}
		}
		printf("\n   -------------\n");
	}
}
玩家下棋函数

函数逻辑:

  • 首先需要玩家进行下棋位置坐标输入,判断是否合法。
  • 合法:继续判断该位置是否已有棋子。
  • 无棋子:可以将该位置设置为玩家棋子。

三子棋 python 三子棋图片_三子棋 python_03

  • 有棋子:则输出提示信息,重新输入。
  • 不合法:输出提示信息,然后重新输入。

代码实现:

void player(char arr[ROW][COL]) {
	int i;
	int j;
	while (1) {
		printf("请输入你要下棋位置的坐标:\n");
		scanf("%d%d", &i, &j);
		if (i < 1 || i > ROW || j < 1 || j > COL) {
			printf("输入错误坐标\n");
			continue;
		}
		if (arr[i - 1][j - 1] == BLANK) {
			arr[i - 1][j - 1] = PLAYER;
			break;
		}
		else {
			printf("该位置已有棋子\n");
		}
	}
}
电脑下棋函数

函数逻辑:

  • 电脑下棋我们使用最简化的设计,就是随机生成(rand函数)下棋位置(行和列),并除去已下棋位置即可。

三子棋 python 三子棋图片_#define_04

代码实现:

void computer(char arr[ROW][COL]) {
	printf("电脑下棋:\n");
	while (1) {
		int i = rand() % ROW;
		int j = rand() % COL;
		if (arr[i][j] == BLANK) {
			arr[i][j] = COMPUTER;
			break;
		}
	}
}
胜负判定函数

函数逻辑:

判断是否连成三个:

  • 连成三个(结束):
  • 竖着三个相连(1,1)(2,1)(3,1)…
  • 横着三个相连(1,1)(1,2)(1,3)…
  • 对角线三个相连(1,1)(2,2)(3,3)…
  • 未连成三个:
  • 判断有无空位:
  • 有空位:继续
  • 无空位:平局(结束)

代码实现:

char judge_game(char arr[ROW][COL]) {
	int i;
	int j;

	//竖着三个
	for (i = 0; i < ROW; i++) {
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != BLANK) {
			return arr[i][0];
		}
	}

	//横着三个
	for (i = 0; i < COL; i++) {
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != BLANK) {
			return arr[0][i];
		}
	}

	//对角线三个
	if ((arr[0][0] == arr[1][1] && 
		arr[1][1] == arr[2][2]) || 
		(arr[0][2] == arr[1][1] &&
		arr[2][0] == arr[1][1]) && 
		arr[1][1] != BLANK) {
		return arr[1][1];
	}

	//未到三个,判断是否还能下棋
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < COL; j++) {
			if (arr[i][j] == BLANK) {
				return CONTINUE;
			}
		}
	}

	//平局
	return DRAW;
}
游戏逻辑函数

函数逻辑:

  • 首先创建二维数组,并将其初始化。
  • 其次使用srand()配合随机数的动态生成。
  • 然后将棋盘展示并进行下棋并判定是否继续,可以用while循环实现。
  • 最后将结束结果用switch结构进行输出。

代码实现:

void tic_tac_toe() {
	char arr[ROW][COL];
	init_board(arr);
	srand((unsigned)time(NULL));
	char result = 0;

	while (1) {
		show_board(arr);
		player(arr);
		result = judge_game(arr);
		if (result != CONTINUE) {
			break;
		}
		show_board(arr);
		system("pause");
		system("cls");
		computer(arr);
		result = judge_game(arr);
		if (result != CONTINUE) {
			break;
		}
	}
	show_board(arr);
	switch (result)
	{
	case COMPUTER:
		printf("电脑胜利!\n");
		break;
	case PLAYER:
		printf("玩家胜利!\n");
		break;
	case DRAW:
		printf("平局!\n");
		break;
	}
}

test.c

菜单展示函数
void menu() {
	printf("***********************\n");
	printf("*****   1. play   *****\n");
	printf("*****   0. exit   *****\n");
	printf("***********************\n");
}
主函数(程序逻辑)

函数逻辑:

  • 首先用do while循环对菜单进行打印并将接收的输入,然后嵌套switch进行条件选择。

代码实现:

int main() {
	int input = 0;
	do
	{
		menu();
		printf("请输入你的选择:\n");
		scanf("%d", &input);
		system("cls");
		switch (input) {
		case 1:
			tic_tac_toe();
			break;
		case 0:
			printf("退出游戏\n");
			return 0;
			break;
		default:
			printf("输入不合法\n");
			break;
		}
		system("pause");
		system("cls");
	} while (input);
}

代码整体实现

game.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define DRAW 'd' //平局
#define CONTINUE 'c' //继续下棋
#define COMPUTER 'O' //电脑下棋
#define PLAYER 'X' //玩家下棋
#define BLANK ' ' //BLANK为空格字符用于初始化棋盘数组
#define ROW 3 //行
#define COL 3 //列

void tic_tac_toe(); //游戏逻辑函数
void init_board(char arr[ROW][COL]); //棋盘初始化函数
void show_board(char arr[ROW][COL]); //显示效果函数
char judge_game(char arr[ROW][COL]); //胜负判定函数
void player(char arr[ROW][COL]); //玩家下棋函数
void computer(char arr[ROW][COL]); //电脑下棋函数

game.c

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

//初始化棋盘
void init_board(char arr[ROW][COL]) {
	int i;
	int j;
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < COL; j++) {
			arr[i][j] = BLANK;
		}
	}
}

//显示棋盘
void show_board(char arr[ROW][COL]) {
	int i;
	int j;
	for (i = 0; i <= ROW; i++) {
		printf(" %d  ", i);
	}
	printf("\n   -------------\n");
	for (i = 0; i < ROW; i++) {
		printf(" %d ", i + 1);
		for (j = 0; j < COL; j++) {
			if (j == 1) {
				printf(" %c ", arr[i][j]);
			}
			else {
				printf("| %c |", arr[i][j]);
			}
		}
		printf("\n   -------------\n");
	}
}


//玩家下棋
void player(char arr[ROW][COL]) {
	int i;
	int j;
	while (1) {
		printf("请输入你要下棋位置的坐标:\n");
		scanf("%d%d", &i, &j);
		if (i < 1 || i > ROW || j < 1 || j > COL) {
			printf("输入错误坐标\n");
			continue;
		}
		if (arr[i - 1][j - 1] == BLANK) {
			arr[i - 1][j - 1] = PLAYER;
			break;
		}
		else {
			printf("该位置已有棋子\n");
		}
	}
}

//电脑下棋
void computer(char arr[ROW][COL]) {
	printf("电脑下棋:\n");
	while (1) {
		int i = rand() % ROW;
		int j = rand() % COL;
		if (arr[i][j] == BLANK) {
			arr[i][j] = COMPUTER;
			break;
		}
	}
}

//判定胜负
char judge_game(char arr[ROW][COL]) {
	int i;
	int j;

	//竖着三个
	for (i = 0; i < ROW; i++) {
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != BLANK) {
			return arr[i][0];
		}
	}

	//横着三个
	for (i = 0; i < COL; i++) {
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != BLANK) {
			return arr[0][i];
		}
	}

	//对角线三个
	if ((arr[0][0] == arr[1][1] && 
		arr[1][1] == arr[2][2]) || 
		(arr[0][2] == arr[1][1] &&
		arr[2][0] == arr[1][1]) && 
		arr[1][1] != BLANK) {
		return arr[1][1];
	}

	//未到三个,判断是否还能下棋
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < COL; j++) {
			if (arr[i][j] == BLANK) {
				return CONTINUE;
			}
		}
	}

	//平局
	return DRAW;
}

void tic_tac_toe() {
	char arr[ROW][COL];
	init_board(arr);
	srand((unsigned)time(NULL));
	char result = 0;

	while (1) {
		show_board(arr);
		player(arr);
		result = judge_game(arr);
		if (result != CONTINUE) {
			break;
		}
		show_board(arr);
		system("pause");
		system("cls");
		computer(arr);
		result = judge_game(arr);
		if (result != CONTINUE) {
			break;
		}
	}
	show_board(arr);
	switch (result)
	{
	case COMPUTER:
		printf("电脑胜利!\n");
		break;
	case PLAYER:
		printf("玩家胜利!\n");
		break;
	case DRAW:
		printf("平局!\n");
		break;
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"game.h"

void menu() {
	printf("***********************\n");
	printf("*****   1. play   *****\n");
	printf("*****   0. exit   *****\n");
	printf("***********************\n");
}

int main() {
	int input = 0;
	do
	{
		menu();
		printf("请输入你的选择:\n");
		scanf("%d", &input);
		system("cls");
		switch (input) {
		case 1:
			tic_tac_toe();
			break;
		case 0:
			printf("退出游戏\n");
			return 0;
			break;
		default:
			printf("输入不合法\n");
			break;
		}
		system("pause");
		system("cls");
	} while (input);
}

IDE

  • Visual Studio 2019