三子棋程序的编写

三子棋是我们每个人在小的时候,和朋友休闲娱乐时,必不可少的一项,本文将会介绍三子棋代码详细的编写过程,但因博主水平有限,暂时还无法实现通过鼠标点击的方式来实现,则暂时使用键盘输入的方式,来实现下棋点位的确定。

大致框架

在正式写程序钱,我们要有一个大概的框架,先编写功能函数,再编写主程序来调用功能函数来实现目标。

首先,我们需要有一个目录,玩家通过输入目录所显示的数字,来实现不同的功能。然后需要显示棋盘,玩家通过输入相应的坐标,来定位到相应的位置,然后计算机判断玩家是否胜利,若玩家胜利,则告诉玩家胜利,接着显示目录,让玩家判断其是否要继续游玩。若并未判断出玩家胜利,则让电脑输出一个随机坐标,后判断电脑是否胜利,若电脑胜利,则输出电脑胜利,后面的操作同玩家胜利。若直到无空位可下时,仍未判断出胜负,则判为平局,后面的操作同玩家胜利。

因此,我们目前判断出需要的功能函数有:执行游戏的函数Game,显示目录的函数Menu,显示棋盘的函数ShowBoard,执行玩家输入操作的函数PlayerMove,执行电脑输入操作的函数ComputerMove,判断是否胜利的函数IsEnd,基本需要的函数就是这些。但若想多次游玩游戏,则需要一个函数InitBoard来初始化所有数据。到此,所有我们需要的函数则构思完毕,现在则将所有函数具体实现,因Game函数需要调用其他的函数模块,所最后编写。

功能函数

显示目录的函数Menu

在目录中,需要提供玩家选项来让玩家选择,是游玩游戏,还是直接退出。

static void Menu()
{
	printf("+-------------------------------+\n");
	printf("| 1. Play              0. Exit  |\n");
	printf("+-------------------------------+\n");
}

显示棋盘的函数ShowBoard

在每次显示棋盘时,先执行一次清屏操作,去除掉之前显示的棋盘。再通过遍历数组的方式,显示棋盘及棋盘不同位置相应的坐标。同时,定义宏定义,INIT代表空白,WHITE代表玩家所下的棋,BLACK代表电脑下的棋。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑

static void ShowBoard(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");
	}
}

执行玩家输入操作的函数PlayerMove

在玩家输入相应的坐标后,判断玩家输入的坐标是否合法,即判断玩家输入的坐标是否在正确的范围内,再判断玩家输入的坐标是否已被占用,若输入的坐标没有问题,则存储玩家输入的数据。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑

static void PlayerMove(char board[][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1){
		printf("Please Enter Postion<x,y># ");
		scanf("%d %d", &x, &y);
		if (x < 1 || y < 1 || x > 3 || y > 3){//判断玩家输入的坐标是否合法
			printf("Enter Postion Error!\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT){//判断玩家输入的坐标是否已被占用
			board[x - 1][y - 1] = WHITE;//存入玩家数据
			break;
		}
		else{
			printf("Postion Is Not Empty!\n");
		}
	}
}

执行电脑输入操作的函数ComputerMove

电脑的数据来自随机数,判断随机数所指向的位置是否被占用即可。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑

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;
		}
	}
}

判断是否胜利的函数IsEnd

遍历所有胜利的情况,即每行,每列及对角线三子连珠的情况。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑
#define DRAW 'D'//胜利
#define NEXT '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];
	}
	for (int i = 0; i < row; i++){
		for (int j = 0; j < col; j++){
			if (board[i][j] == INIT){
				return NEXT;//继续
			}
		}
	}
	return DRAW;//已判断出胜利
}

初始化数据的函数InitBoard

遍历数组,将数组中所有数据存为空白。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑

static void InitBoard(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;//将数组中数据清空
		}
	}
}

执行游戏的函数Game

首先需要创建一个函数来记录每个位置的情况,并初始化,后进入循环反复执行游戏游玩的相关程序。先显示键盘,后让玩家输入,判断是否胜利,若胜利,则退出循环,若并未胜利,则继续显示棋盘,电脑进行输入,判断电脑是否胜利,若胜利,则退出循环,若并未胜利,则继续执行循环。若因为玩家胜利或者电脑胜利,再或者平局,退出了循环,则判断退出循环的原因,并执行相关显示结束循环的输出程序。

#define ROW 3
#define COL 3
#define INIT ' '//空白
#define WHITE 'X' //玩家
#define BLACK 'O' //电脑
#define DRAW 'D'//胜利
#define NEXT 'N'//继续

void Game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);

	srand((unsigned long)time(NULL));
	char result = 0;
	while (1){
		ShowBoard(board, ROW, COL);
		PlayerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT){
			break;
		}
		ShowBoard(board, ROW, COL);
		ComputerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT){
			break;
		}
	}
	ShowBoard(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"); //Do Nothing!
		break;
	}
}

主调函数main函数

到此,所有需要的功能都编写完成,再继续在main函数中编写进入游戏前的程序。

int main()
{
	int select = 0;
	int quit = 0;
	while (!quit){
		Menu();
		printf("Please Select# ");
		scanf("%d", &select);
		switch (select){
		case 1:

			Game();
			break;
		case 0:
			quit = 1;
			break;
		default:
			printf("Enter Error, Try Again!\n");
			break;
		}
	}
	printf("ByeBye!\n");
	system("pause");
	return 0;
}

至此,所有三子棋的程序都已经编写完毕,后面为将前面所有代码合在一起的结果。其中game.h文件中,主要为宏定义和函数的声明;game.c文件中为所有功能函数的编写;main.c文件中为主调函数的编写。

合集

game.c文件

#ifndef __GAME_H__
#define __GAME_H__

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

#define ROW 3
#define COL 3
#define INIT ' '
#define WHITE 'X' //Player
#define BLACK 'O' //Computer
#define DRAW 'D'
#define NEXT 'N'

#pragma warning(disable:4996)

extern void Game();

#endif

game.c文件


#include "game.h"

void Menu()
{
	printf("+-------------------------------+\n");
	printf("| 1. Play              0. Exit  |\n");
	printf("+-------------------------------+\n");
}

static void ShowBoard(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); //2
		for (int j = 0; j < col; j++){
			printf("| %c ", board[i][j]); //12
		}
		printf("\n--------------\n");
	}
}

static void PlayerMove(char board[][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1){
		printf("Please Enter Postion<x,y># ");
		scanf("%d %d", &x, &y);
		if (x < 1 || y < 1 || x > 3 || y > 3){
			printf("Enter Postion Error!\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT){
			board[x - 1][y - 1] = WHITE;
			break;
		}
		else{
			printf("Postion Is Not Empty!\n");
		}
	}
}

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;
		}
	}
}

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];
	}
	for (int i = 0; i < row; i++){
		for (int j = 0; j < col; j++){
			if (board[i][j] == INIT){
				return NEXT;
			}
		}
	}
	return DRAW;
}

static void InitBoard(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;
		}
	}
}

void Game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);

	srand((unsigned long)time(NULL));
	char result = 0;
	while (1){
		ShowBoard(board, ROW, COL);
		PlayerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT){
			break;
		}
		ShowBoard(board, ROW, COL);
		ComputerMove(board, ROW, COL);
		result = IsEnd(board, ROW, COL);
		if (result != NEXT){
			break;
		}
	}
	ShowBoard(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"); //Do Nothing!
		break;
	}
}

main.c文件

#include "game.h"

int main()
{
	int select = 0;
	int quit = 0;
	while (!quit){
		Menu();
		printf("Please Select# ");
		scanf("%d", &select);
		switch (select){
		case 1:

			Game();
			break;
		case 0:
			quit = 1;
			break;
		default:
			printf("Enter Error, Try Again!\n");
			break;
		}
	}
	printf("ByeBye!\n");
	system("pause");
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值