三子棋(C语言实现)

2024-02-12 16:48
文章标签 语言 实现 三子

本文主要是介绍三子棋(C语言实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 实现思路
    • 1、存储棋盘
    • 2、初始化
    • 3、用户落子
    • 4、判断检查
    • 5、判断本局游戏的状态
    • 6、电脑落子
    • 7、判断检查
    • 8、判断本局游戏的状态
  • 具体完整代码如下

三子棋实现
三子棋是一个很古老的民间传统游戏,玩起来也非常便捷。三子棋也叫做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 0extern 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;
}

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

这篇关于三子棋(C语言实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/703084

相关文章

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端