三子棋(C语言实现)


三子棋实现
三子棋是一个很古老的民间传统游戏,玩起来也非常便捷。三子棋也叫做OOXX棋,井字棋等,用“井”字分出3×3的格子,双方轮流下棋子(可以用O或者X来区别),只要将自己的棋子连成直线就赢了。

实现思路

注:以下每一个步骤或多或少用到了宏定义,在此做一说明

#define ROW 3
#define COL 3
#define INIT ' '
#define WHITE 'X'
#define BLACK 'O'
#define NEXT 'D'
#define DRAW 0

1、存储棋盘

用二维数组char board[3][3] 实现

char board[ROW][COL];

2、初始化

从用户角度来看,游戏开始时展现的棋盘应该为空,故而用字符空格‘ ’对其进行初始化操作

static void Init(char board[][COL],int row ,int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = INIT;
		}
	}
}

3、用户落子

初始化完成后用户先进行落子,落子的具体操作是用户输入对应的坐标,系统为其对应位置写入X代表用户落子成功。

4、判断检查

检查用户落子位置是否合法,若合法进行下一步操作做,若不合法返回上一步

用户层面判断落子是否合法有两方面:
第一:判断用户输入的坐标是否在定义的二维数组内
第二:判断用户输入的坐标所对应的位置能不能放入对应的字符(判断对应位置是否为空格,若是,就可以落子,否则不行)

static void PlayerMove(char board[][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("Please Enter Your  Position<x,y>#\n");
		scanf("%d %d", &x, &y);
		if (x<1 || x>3 || y<1 || y>3)
		{
			printf("Enter Error! Try Again\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT)
		{
			board[x - 1][y - 1] = WHITE;
			break;
		}
		else
		{
			printf("This position is not empty,please enter again!\n");
		}
	}
}

5、判断本局游戏的状态

一局游戏有四种状态,赢、输、平局、继续
通过对棋盘的每一行每一列以及每一条对角线判断,进而得到本局游戏的状态

static char IsEnd(char board[][COL], int row, int col)
{
	//判断行
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && \
			board[i][1] == board[i][2] && \
			board[i][0] != INIT)
		{
			return board[i][0];
		}
	}
	//判断列
	for (int j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && \
			board[1][j] == board[2][j] && \
			board[0][j] != INIT)
		{
			return board[0][j];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && \
		board[1][1] == board[2][2] && \
		board[1][1] != INIT)
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && \
		board[1][1] == board[2][0] && \
		board[1][1] != INIT)
	{
		return board[1][1];
	}
	//若以上条件均不满足,说明该局游戏应继续
	return NEXT;
}

6、电脑落子

电脑落子是由系统产生随机坐标值并在对应的二维数组中填入相应的字符O

7、判断检查

检查用户落子位置是否合法,若合法进行下一步操作做,若不合法返回上一步
电脑落子判断
随机数通过模运算之后得到的坐标值一定在二维数组内,所以只需要判断坐标对应的二维数组中的位置是否为空格即可

static void ComputerMove(char board[][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % ROW;
		int y = rand() % COL;
		if (board[x][y] == INIT)
		{
			board[x][y] = BLACK;
			break;
		}
	}	
}

8、判断本局游戏的状态

一局游戏有四种状态,赢、输、平局、继续
通过对棋盘的每一行每一列以及每一条对角线判断,进而得到本局游戏的状态(此次操作与步骤5一致)

具体完整代码如下

采用多文件模式
game.h文件

# pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>

#define ROW 3
#define COL 3
#define INIT ' '
#define WHITE 'X'
#define BLACK 'O'
#define NEXT 'D'
#define DRAW 0

extern void Game();
extern void menu();

game.c文件

#include "game.h"

void Menu()
{
	printf("+----------------------+\n");
	printf("|1.play          2.exit|\n");
	printf("+----------------------+\n");
}
//初始化棋盘
static void Init(char board[][COL],int row ,int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = INIT;
		}
	}
}
static void Showbard(char board[][COL], int row, int col)
{
	system("cls");
	printf(" ");
	for (int i = 0; i <col; i++)
	{
		printf("%4d",i+1);
	}
	printf("\n----------------\n");
	for (int i = 0; i < row; i++)
	{
		printf("%-2d", i+1);
		for (int j = 0; j < col; j++)
		{
			printf("| %c ", board[i][j]);
		}
		printf("\n----------------\n");
	}
}
static void PlayerMove(char board[][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("Please Enter Your  Position<x,y>#\n");
		scanf("%d %d", &x, &y);
		if (x<1 || x>3 || y<1 || y>3)
		{
			printf("Enter Error! Try Again\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT)
		{
			board[x - 1][y - 1] = WHITE;
			break;
		}
		else
		{
			printf("This position is not empty,please enter again!\n");
		}
	}
}

static char IsEnd(char board[][COL], int row, int col)
{
	//判断行
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && \
			board[i][1] == board[i][2] && \
			board[i][0] != INIT)
		{
			return board[i][0];
		}
	}
	//判断列
	for (int j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && \
			board[1][j] == board[2][j] && \
			board[0][j] != INIT)
		{
			return board[0][j];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && \
		board[1][1] == board[2][2] && \
		board[1][1] != INIT)
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && \
		board[1][1] == board[2][0] && \
		board[1][1] != INIT)
	{
		return board[1][1];
	}
	return NEXT;
}

static void ComputerMove(char board[][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % ROW;
		int y = rand() % COL;
		if (board[x][y] == INIT)
		{
			board[x][y] = BLACK;
			break;
		}
	}	
}

void Game()
{
	srand((unsigned long)time(NULL));
	char board[ROW][COL];
	Init(board, ROW, COL);
	char result = 0;
	while (1)
	{
		Showbard(board, ROW, COL);
		PlayerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT)
		{
			break;
		}
		Showbard(board, ROW, COL);
		ComputerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT)
		{
			break;
		}
	}
	Showbard(board, ROW, COL);
	switch (result)
	{
	case WHITE:
		printf("You Win\n");
		break;
	case BLACK:
		printf("You lose\n");
		break;
	case DRAW:
		printf("you == computer\n");
		break;
	default:
		printf("Bug!\n");
		break;
	}
}

main.c文件

#include "game.h"

int main()
{
	
	int quit = 0;
	while (!quit)
	{
		Menu();
		int select = 0;
		printf("Please Enter Your Choose#");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			break;
		case 0:
			printf("ByeBye!\n");
			quit = 1;
			break;
		default:
			printf("Bug!\n");
			break;
		}
	}
	system("pause");
	return 0;
}

最后贴张运行截图
这只是玩到最后的结果,读者有兴趣可以直接在自己的环境下运行体验一下
在这里插入图片描述

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suk-god

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值