五子棋数据结构课程设计报告(五子棋课程设计实验报告)
数据结构实验的实验报告怎么写
数据库课程设计
“数据库课程设计”是数据库系统及应用课程的后续实验课,是进一步巩固学生的数据库知识,加强学生的实际动手能力和提高学生综合素质。
一、 课程设计目的
课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。提高学生适应实际,实践编程的能力。课程设计的目的:
1. 加深对数据库原理、程序设计语言的理论知识的理解和应用水平;
2. 在理论和实验教学基础上进一步巩固已学基本理论及应用知识并加以综合提高;
3. 学会将知识应用于实际的方法,提高分析和解决问题的能力,增强动手能力;
4. 为毕业设计和以后工作打下必要基础。
二、课程设计要求
运用数据库原理的基本理论与应用知识,在微机RDBMS(SQL Server)的环境上建立一个数据库应用系统。要求把现实世界的事物及事物之间的复杂关系抽象为信息世界的实体及实体之间联系的信息模型,再转换为机器世界的数据模型和数据文件,并对数据文件实施检索、更新和控制等操作。
1. 用E-R图设计选定题目的信息模型;
2. 设计相应的关系模型,确定数据库结构;
3. 分析关系模式各属于第几范式,阐明理由;
4. 设计应用系统的系统结构图,确定系统功能;
5. 通过设计关系的主码约束、外码约束和使用CHECK实现完整性控制;
6. 为参照关系设计插入、删除、修改触发器;
7. 实现应用程序设计、编程、优化功能;
8. 对系统的各个应用程序进行集成和调试,进一步优化系统功能、改善系统用户界面完成实验内容所指定的各项要求;
9. 分析遇到的问题,总结并写出课程设计报告;
10. 自我评价
三、实验环境
开发环境VC++、C#、ASP或JAVA;ODBC/JDBC;数据库SQL Server
四、上机实现内容
1. 创建数据库的结构
2. 创建各基本表的结构
3. 编制系统各功能模块,完成数据的管理(增、删、改)及统计查询。对于程序运行界面不做考核的重点。
五、课程设计考核
1.对学生到实验室的情况进行不定时统计;
2.出勤率+课程设计报告+课程设计所开发的应用系统+其他(上机抽查和提问)=综合评定成绩。
3.课程设计结束时请将下列资料上交:
(1) 课程设计报告;
(2) 所开发的应用系统的源程序、安装和使用说明;
(3) 将(1)(2)中的资料压缩成一个压缩包,压缩包文件的命名规则:班级+学号(末2位)+姓名(例如:计科090101王鹏晓);
(4) 班长将本班每人的(3)中的压缩包刻录成光盘连同打印的课程设计报告收齐,交给任课教师。
附录﹑课程设计题目
题目1:课程设计选题管理系统(1,24)
包括三大模块:
? 课程设计题目维护与查询:题目的添加、修改和删除;按题目类型、名称和关键字查询以及已选与未选题目的查询;
? 学生信息维护与查询;
? 学生选题维护与管理:学生选题及查询;
具体功能细化:
? 前台学生选题:学生上网登录系统进行选题;
? 前台教师出题:
? 教师添加、修改和删除题目;
? 教师确认学生的选题;
? 后台管理出题和选题
? 添加用户及权限
题目2:书店管理系统(23)
包括四大模块:
? 售书(图书销售管理及销售统计,查询)
? 进书(通过书目,向发行商下定单订购图书)
? 库存(图书库存,统计)
? 相关查询
题目3:图书馆管理系统(11)
包括四大模块:
? 图书的查询
? 借书
? 还书
? 图书的预约
题目4:库存管理系统(8)
包括四大模块:
? 商品目录建立
? 商品入库管理
? 商品出库管理
? 商品库存查询
题目5:工资管理系统(1 人)41
包括四大模块:
? 系统数据初始化
? 员工基本信息数据的输入、修改、删除;
? 员工个人信息及工资表的查询;
? 员工工资的计算;
参考数据如下:
? 员工基本状况:包括员工号、员工姓名、性别、所在部门、工资级别、工资等级等。
? 工资级别和工资金额:包括工资等级、工资额。
? 企业部门及工作岗位信息:包括部门名称、工作岗位名称、工作岗位工资等。
? 工龄和工资金额:包括工龄及对应工资额。
? 公司福利表:包括福利名称、福利值。
? 工资信息:包括员工号、员工姓名、员工基础工资、员工岗位工资、员工工龄工资、公司福利、员工实得工资。
题目6:酒店客房管理系统 (1 人)14,26
包括四大模块:
? 前台操作:包括开房登记、退房结账和房状态查看
? 预订管理:包括预订房间、预订入住和解除预订
? 信息查询:包括在住客人列表、预订客人列表和历史客人列表
? 报表统计:包括开房记录统计、退房结账和预订房间统计
? 员工基本信息数据的输入、修改、删除;
参考数据如下:
? 住店管理:客人姓名、证件号码、房号、入住时期、预计离开日期、结账离开日期、应付金额
? 客人信息:姓名、性别、证件类型、证件号码、联系电话
? 房间信息:房号、房类型、价格、押金、房状态 预订房间
? 客人姓名、性别、房类型、房号、价格、证件类型、证件号码、联系电话、入住日期、预计离开日期、历史信息
题目7:旅行社管理信息系统(1 人)3
包括如下模块:
? 旅游团队、团队团员及旅游路线相关信息的输入
? 旅游团队、团队团员及旅游路线相关信息的维护(修改、浏览、删除和撤销)
? 旅游团队管理信息的查询(如按团队编号)
? 团队团员基本情况的查询(可选多种方式)
? 旅游路线相关信息的查询(如按线路编号)
? 旅游路线排行榜发布。
? 数据备份,更改密码。
参考数据如下:
? 团员信息表(路线编号,团队编号,团员编号,姓名,性别,电话,通信地址,身份证号码, 团费交否,备注)
? 线路信息表(路线名称,团费,简介,图形,路线编号)
? 团队信息表(团队编号,路线编号,团员人数,出发日期,返程日期)
? 旅游团队信息表(团队编号,团队负责人,团员人数,建团时间,是否出发,团费,盈亏)
密码信息(操作员,密码)
题目8:报刊订阅管理系统 (1 人)25,35
包括如下模块:
? 登录功能:登录统为身份验证登录。分为管理员登录和一般用户登录。分别通过不 同的用户名和密码进入报刊订阅管理界面,新的用户需要注册。
? 录入新信息功能:对于管理员,包括新用户信息和新报刊信息的录入功能,信息一旦 提交就存入到后台数据库中;普通用户自行注册进行可以修改个人信息。
? 订阅功能:用户可以订阅报刊,系统自动计算所需金额,并显示在界面上;管理员不 可订阅报刊,必须以用户身份订阅报刊。
? 查询功能:用户可以查询并显示自己所订阅的信息;管理员可以按人员、报刊、部门 分类查询。查询出的信息显示在界面上,并且可以预览和打印出结果。
? 统计功能:管理员可以按用户、部门、报刊统计报刊的销售情况,并对一些重要的订 阅信息进行统计;普通用户可以统计出自己的订阅情况,并且可以预览和打印出结果。
? 系统维护功能:数据的安全管理,主要是依靠管理员对数据库里的信息进行备份和恢 复,数据库备份后,如果出了什么意外可以恢复数据库到当时备份的状态,这提高了系统和 数据的安全性,有利于系统的维护
参考数据如下:
? 管理员表(Adminuser) :管理员名、密码。
? 部门表(Department) :部门号,部门名。
? 用户表(Users) :用户账号、密码、真实姓名、身 份证号、联系电话,联系地址,部门号(和部门表有关)等。
? 报刊类别表(NewspaperClass) :分类编号、 分类名称。
? 报刊信息表(Newspaper) :报刊代号、报刊名称、出版 报社、出版周期、季度报价、内容介绍、分类编号(和报刊类别表有关)等。
? 订单表(Order) :订单编号、用户编号、报刊代号、订阅份数、订阅月数等。
题目9:计算机等级考试教务管理系统(2 人)32
包括四大模块:
? 用户设置:对考点代码,考点名称进行设置,设置用户与密码;系统复位:即清除上一次考试数据(在之前存入历史)
? 报名管理: 报各库录入(姓名不能不空,之间不能有空格) 增加、删除、修改、浏览
? 准考证管理:准考证生成规则:xxx+yy+zz+kk,其中 XXX 为考点代码;YY 为语言代码,XX 为考场号,KK 为座位号 同一级别、语言应根据报名初始库信息按随机数生成准考证,同一考点最多可有 99*30=2970 名考生;如已生成准考证号,再重新生成准考证号,应该给予提示。 准考证打印
? 考务管理:考生信息查询、浏览、打印
? 成绩管理:成绩数据录入、接收 成绩合成(总成绩=笔试成绩*0.6+上机成绩*0.4),按大于或等于 60 合格
参考数据如下:
? 初始报名表(准考证号(为空) ,报名号(主键) ,级别+语言种类(外键) ,姓名,性别, 出生年份,民族,身份证号,联系地址,联系电话,照片,备注,参加培训)
? 含准考证号的报名表(准考证号(为主键) ,报名号,级别+语言种类(外键) ,姓名,性别, 出生年份,民族,身份证号,联系地址,联系电话,照片,备注,参加培训)
? 成绩表(准考证号,笔试成绩,上机成绩,总成绩) 级别语言代码表(级别语言代码,级别+语言)
? 用户信息表(考点代码,考点名称,用户名,密码)
题目10:人事管理系统(1 人)21
包括四大模块:
? 登录管理:包括操作员管理,口令设置,权限管理
? 人员管理:包括人事数据维护、人事信息查询和人事信息统计
? 工资管理
? 部门管理:包括部门表,职称表和年份表
? 查询及报表打印
参考数据如下:
? 人事表(编号,姓名,性别,出生日期,工作日期,部门代码,职称,婚否,简历,相片)
? 工资表(基本工资,岗位津贴,奖励,应发工资,水电,保险,实发工资)
? 部门表(代码,部门名称)
? 职称表(职称代码,职称名称)
? 年份表(年份代码,年份名称)
? 操作员表(操作员代码,操作员姓名,口令,部门,电话)
系统日志表(操作员代号,操作员姓名,登录时间,离开时间)
题目11:商品销售管理系统(1 人)19
包括四大模块:
? 用户登录
? 基本信息管理:包括销售情况、商品信息、库存表、员工表等信息的录入、浏览、修改、撤销、删除和查询等
? 商品销售管理:包括商品售出、退回和入库
? 盘点:包括库存盘点、当日销售盘点
参考数据如下:
? 商品信息表(商品编号,商品名称,品牌,型号,销售单价) 商品编号=类别代码(1 位)+品名代码(1 位)+品牌代码(2 位)+型号代码(2 位)
? 销售情况表(成交编号,商品编号,销售数量,总金额,销售日期,员工编号)
? 库存表(商品编号,供货商编号,进货日期,进货价,库存数量)
? 员工表(员工编号,员工姓名,性别,基本工资,职务,密码)
? 供货商表(供货商编号,供货商名称,所在地,联系电话)
? 员工资料表(员工编号,员工姓名,是否党员,简历,照片)
题目12:学生成绩管理系统(1 人)29
包括四大模块:
? 基本数据管理:包括院系管理,专业管理(设置院系下面的专业),班级管理(设置专业下面的班级),课程管理(设置相应专业下面的课程)
? 学生信息管理:包括基本信息录入、基本信息修改
? 学生成绩管理:包括学生成绩录入、学生成绩修改
? 信息查询:包括基本信息查询、成绩信息查询、学校人数统计
? 系统管理:用户管理、数据备份和系统帮助
参考数据如下:
? 院系信息(院系代码,院系名称)
? 院系专业信息(班级、院系代码,专业)
? 学生基本信息(班号,学号,姓名,性别,出生年月,籍贯,政治面貌,身份证号,入学年月,家庭地址,邮政编码,图片信息,备注)
? 学生成绩表(学号,课号,成绩,备注)
? 课程表(课号,课程名称,学期,备注)
? 班表(班号,班级名称)
? 用户信息表(用户名,密码,用户标识)
题目13:火车售票管理系统(4 人)36
包括四大模块:
? 售票管理
? 订票管理
? 信息查询
? 系统维护
参考数据如下:
? 车次信息表(车次,始发站,终点站,发车时间,到达时间)
? 订票信息表(车次,座位号,发车时期,发车时间,座位等级,票价)
? 车次座位等级分配及座位占用表(车次,座位号,座位等级,票价,占用标志)
? 用户信息表(用户名,密码,用户标识)
题目14:小型物业管理系统(1 人)
包括四大模块:
? 房源管理:对原始资料的录入、修改、查询和刷新。一般用户可以查询与房间有关 的统计资料;物业主管可其进行增、删、改、插等操作
? 租房管理:对房产出租,退租以及租房面积调整。其中物业主管可对其进行房租金 额计算和收款操作,一般用户对其查询
? 水电处理:根据租房资料,结合当月水、电量进行分摊,完成应收水电费。其中物 业主管对其进行计算,其他查询
? 交款处理:提供收款和发票打印以及交款数据查询
? 查询处理:对租房资料、交款资料,发票资料进行查询
参考数据如下:
? 房源资料(名称,面积,月租,物业,仓库)
? 租房资料(名称,面积,单位,月租,物业,押金,仓库)
? 水电资料(单位,电量,水量,电费,水费)
? 交费资料(收费项目,应收日期,应收金额,已收金额,未收金额,本次收款)
? 发票资料(单位,房租,电费,水费,物业)
? 权限资料(用户,密码,房源管理,租房管理,水电管理,交费管理,发票管理,系统维护) 其中系统管理员,有权进行系统维护;单位内部物业主管,有权进行物业资源调配、单元出 租,退租和收款开票操作;物业管理员,有权进行水电处理和收款处理等操行;租户代表, 有权进行种类费的查询操作
题目15:机房收费管理系统(1 人)7,34
包括四大模块:
? 登录模块
? 上机管理模块 说明:上机登记时,余额不足 3 元或卡处于挂失状态,则拒绝登记 每位同学的一次上机形成一条记录,每 36S 遍历一次上机记录表,对表中所有正上机字段为 TRUE 的记录的上机用时增加 36S,同时从上机卡表的余额减少
? 上机卡管理模块
? 充值挂失模块
? 查找统计模块:统计某天上机的总时数、每次上机的平均时数和机房的收入;某学 生上机的次数、上机总时数、每次上机平均时间;挂失和查询余
参考数据如下:
? 上机卡(卡号,姓名,专业班级,余额,状态) 状态的取值有:正常(能自费上机)
? 挂失上机记录(卡号,上机日期,开始时间,上机用时,正上机,管理号代码),上机用时记录学生上机时间(S);正上机是一个布尔型,为 True 表示正上机,每 36 秒刷新 其上机用时并扣除上机费用,为 False 表示上机结束。上机记录表永久保存,用于事后查询 和统计 管理员(代码,姓名,口令)
?
题目16:高校药房管理(1 人)31
包括四大模块:
? 基础数据处理:包括医生和药剂师名单的录入,修改,删除及查询
? 营业数据处理:包括药品进货上柜,处理划价,配药,柜存药品查询,处方综合查 询,交接班结转清。
参考数据如下:
? 药品信息表(货号,货名,计量单位,进货数量,进货单价,出售单价,进货日期,收货人 和供应商)
? 处方信息(编号,患者姓名,医生姓名,药剂师姓名,处方日期,配药日期) 处方药品信息(处方编号,药品货号,计量单位,配药数量,销售单价,已配药否)
? 医生名单和药剂师名单表(姓名)
?
题目17:考勤管理系统(2 人)40
包括四大模块:
? 记录每个员工每天所有进入公司的时刻和离开公司的时刻。
? 每天结束时自动统计当天的工作时间
? 每天结束时自动统计当天迟到或早退的次数。
? 对于弹性工作制,每天结束时自动统计当月的工时,并自动算出当月欠缺或富余的 时间
? 每个月末统计该月的工作时间判断是束足够
? 每个月末统计该月的工作天数并判断是否足够
? 管理人员查询并修改工作时间(特殊情况下修改)
? 管理人员账户管理(如设置密码等)
? 管理人员设定早退及迟到的条件,每个月的工作时间
? 管理人员设定每个月的工作日期及放假日期
参考数据如下:
? 员工信息(工号,姓名,年龄,入职时间,职位,性别,密码)
? 配置信息(上班时间小时,上班时间分钟,下班时间小时,下班时间分钟,每天工作时间)
? 每月统计数据表(工号,姓名,剩余的时间,迟到的次数,早退的次数,工作天数)
? 每天统计信息表(工号,姓名,小时,分钟,动作,时间) 其中动作指的时入或离开公司
?
题目18:单位房产管理系统(2 人)33,10
包括四大模块:
? 系统模块:完成数据库维护、系统关闭功能
? 物业费用模块:完成本月物业的计费、历史资料查询和财务部门接口传送数据、物 业相关费用单价设置
? 房屋资源模块:对房屋资源进行添加、列表显示、查询
? 职工信息模块:对职工进行添加、列表显示、查询以及相应部门、职务进行维护
? 帮助模块:对用户使用本系统提供在线帮助
参考数据如下:
? 职工(编号,姓名,性别,参加工作时间,行政职务,专业技术职务,评上最高行政职务时 间,评上最高专业技术职务时间,双职工姓名,现居住房号,档案号,房产证号,所在部门 编号,是否为户主)
? 部门(编号,部门名称) 住房级别表(编号,级别,住房标准,控制标准,级别分类)
? 房产情况(编号,房号,使用面积,现居住人 id,上一个居住人 id,最早居住人 ID,阳台面积)
? 物业费用(编号,房号,水基数,水现在值,电基数,电现在值,燃气基数,燃气现在值, 当前年份,当前月份)
? 价格标准(编号,水单价,电单价,燃气单价)
题目19:标准化考试系统 (2 人)15,39
功能要求: 设计一个简单的标准化考试系统,仅有单项选择题、多项选择题和判断题功能即可。
包括四大模块:
? 题库管理:实现试题的录入、修改、删除功能;
? 考试子系统:能够实现考生做题、结果自动存入到数据库中,有时间提示;
? 选择身份(登录)功能:系统能够记录考生输入的登录信息及交卷信息;
? 自动评分功能:考生交卷后能自动评分;
? 查看成绩功能:能够查询考生相关信息(包含成绩等)。
参考数据如下:
其它可供选择的题目:
网上教务评教系统130,127,133 16
学生日常行为评分管理系统232,110,230
网上鲜花店 38
基于BS结构的工艺品销售系统12
基于BS结构的校园二手物品交易网站 37
大学生就业管理系统201,208,234
题库及试卷管理系统
数据库原理及应用
课程设计报告
题目: 课程设计选题管理系统
所在学院:
班 级:
学 号:
姓 名: 李四
指导教师:
2011年12月 日
目录
一、 概述
二、需求分析
三、概念设计
四、逻辑设计
五、系统实现
六、小结
一、概述
c语言五子棋游戏存盘怎么设计
#include stdio.h
#include bios.h
#include ctype.h
#include conio.h
#include dos.h
#define CROSSRU 0xbf /*右上角点*/
#define CROSSLU 0xda /*左上角点*/
#define CROSSLD 0xc0 /*左下角点*/
#define CROSSRD 0xd9 /*右下角点*/
#define CROSSL 0xc3 /*左边*/
#define CROSSR 0xb4 /*右边*/
#define CROSSU 0xc2 /*上边*/
#define CROSSD 0xc1 /*下边*/
#define CROSS 0xc5 /*十字交叉点*/
/*定义棋盘左上角点在屏幕上的位置*/
#define MAPXOFT 5
#define MAPYOFT 2
/*定义1号玩家的操作键键码*/
#define PLAY1UP 0x1157/*上移--'W'*/
#define PLAY1DOWN 0x1f53/*下移--'S'*/
#define PLAY1LEFT 0x1e41/*左移--'A'*/
#define PLAY1RIGHT 0x2044/*右移--'D'*/
#define PLAY1DO 0x3920/*落子--空格键*/
/*定义2号玩家的操作键键码*/
#define PLAY2UP 0x4800/*上移--方向键up*/
#define PLAY2DOWN 0x5000/*下移--方向键down*/
#define PLAY2LEFT 0x4b00/*左移--方向键left*/
#define PLAY2RIGHT 0x4d00/*右移--方向键right*/
#define PLAY2DO 0x1c0d/*落子--回车键Enter*/
/*若想在游戏中途退出, 可按 Esc 键*/
#define ESCAPE 0x011b
/*定义棋盘上交叉点的状态, 即该点有无棋子 */
/*若有棋子, 还应能指出是哪个玩家的棋子 */
#define CHESSNULL 0 /*没有棋子*/
#define CHESS1 'O'/*一号玩家的棋子*/
#define CHESS2 'X'/*二号玩家的棋子*/
/*定义按键类别*/
#define KEYEXIT 0/*退出键*/
#define KEYFALLCHESS 1/*落子键*/
#define KEYMOVECURSOR 2/*光标移动键*/
#define KEYINVALID 3/*无效键*/
/*定义符号常量: 真, 假 --- 真为1, 假为0 */
#define TRUE 1
#define FALSE 0
/**********************************************************/
/* 定义数据结构 */
/*棋盘交叉点坐标的数据结构*/
struct point
{
int x,y;
};
/**********************************************************/
/*自定义函数原型说明 */
void Init(void);
int GetKey(void);
int CheckKey(int press);
int ChangeOrder(void);
int ChessGo(int Order,struct point Cursor);
void DoError(void);
void DoOK(void);
void DoWin(int Order);
void MoveCursor(int Order,int press);
void DrawCross(int x,int y);
void DrawMap(void);
int JudgeWin(int Order,struct point Cursor);
int JudgeWinLine(int Order,struct point Cursor,int direction);
void ShowOrderMsg(int Order);
void EndGame(void);
/**********************************************************/
/**********************************************************/
/* 定义全局变量 */
int gPlayOrder; /*指示当前行棋方 */
struct point gCursor; /*光标在棋盘上的位置 */
char gChessBoard[19][19];/*用于记录棋盘上各点的状态*/
/**********************************************************/
/**********************************************************/
/*主函数*/
void main()
{
int press;
int bOutWhile=FALSE;/*退出循环标志*/
Init();/*初始化图象,数据*/
while(1)
{
press=GetKey();/*获取用户的按键值*/
switch(CheckKey(press))/*判断按键类别*/
{
/*是退出键*/
case KEYEXIT:
clrscr();/*清屏*/
bOutWhile = TRUE;
break;
/*是落子键*/
case KEYFALLCHESS:
if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/
DoError();/*落子错误*/
else
{
DoOK();/*落子正确*/
/*如果当前行棋方赢棋*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile = TRUE;/*退出循环标志置为真*/
}
/*否则*/
else
/*交换行棋方*/
ChangeOrder();
ShowOrderMsg(gPlayOrder);
}
break;
/*是光标移动键*/
case KEYMOVECURSOR:
MoveCursor(gPlayOrder,press);
break;
/*是无效键*/
case KEYINVALID:
break;
}
if(bOutWhile==TRUE)
break;
}
/*游戏结束*/
EndGame();
}
/**********************************************************/
/*界面初始化,数据初始化*/
void Init(void)
{
int i,j;
char *Msg[]=
{
"Player1 key:",
" UP----w",
" DOWN--s",
" LEFT--a",
" RIGHT-d",
" DO----space",
"",
"Player2 key:",
" UP----up",
" DOWN--down",
" LEFT--left",
" RIGHT-right",
" DO----ENTER",
"",
"exit game:",
" ESC",
NULL,
};
/* 先手方为1号玩家 */
gPlayOrder = CHESS1;
/* 棋盘数据清零, 即棋盘上各点开始的时候都没有棋子 */
for(i=0;i19;i++)
for(j=0;j19;j++)
gChessBoard[i][j]=CHESSNULL;
/*光标初始位置*/
gCursor.x=gCursor.y=0;
/*画棋盘*/
textmode(C40);
DrawMap();
/*显示操作键说明*/
i=0;
textcolor(BROWN);
while(Msg[i]!=NULL)
{
gotoxy(25,3+i);
cputs(Msg[i]);
i++;
}
/*显示当前行棋方*/
ShowOrderMsg(gPlayOrder);
/*光标移至棋盘的左上角点处*/
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*画棋盘*/
void DrawMap(void)
{
int i,j;
clrscr();
for(i=0;i19;i++)
for(j=0;j19;j++)
DrawCross(i,j);
}
/*画棋盘上的交叉点*/
void DrawCross(int x,int y)
{
gotoxy(x+MAPXOFT,y+MAPYOFT);
/*交叉点上是一号玩家的棋子*/
if(gChessBoard[x][y]==CHESS1)
{
textcolor(LIGHTBLUE);
putch(CHESS1);
return;
}
/*交叉点上是二号玩家的棋子*/
if(gChessBoard[x][y]==CHESS2)
{
textcolor(LIGHTBLUE);
putch(CHESS2);
return;
}
textcolor(GREEN);
/*左上角交叉点*/
if(x==0y==0)
{
putch(CROSSLU);
return;
}
/*左下角交叉点*/
if(x==0y==18)
{
putch(CROSSLD);
return;
}
/*右上角交叉点*/
if(x==18y==0)
{
putch(CROSSRU);
return;
}
/*右下角交叉点*/
if(x==18y==18)
{
putch(CROSSRD);
return;
}
/*左边界交叉点*/
if(x==0)
{
putch(CROSSL);
return;
}
/*右边界交叉点*/
if(x==18)
{
putch(CROSSR);
return;
}
/*上边界交叉点*/
if(y==0)
{
putch(CROSSU);
return;
}
/*下边界交叉点*/
if(y==18)
{
putch(CROSSD);
return;
}
/*棋盘中间的交叉点*/
putch(CROSS);
}
/*交换行棋方*/
int ChangeOrder(void)
{
if(gPlayOrder==CHESS1)
gPlayOrder=CHESS2;
else
gPlayOrder=CHESS1;
return(gPlayOrder);
}
/*获取按键值*/
int GetKey(void)
{
char lowbyte;
int press;
while (bioskey(1) == 0)
;/*如果用户没有按键,空循环*/
press=bioskey(0);
lowbyte=press0xff;
press=press0xff00 + toupper(lowbyte);
return(press);
}
/*落子错误处理*/
void DoError(void)
{
sound(1200);
delay(50);
nosound();
}
/*赢棋处理*/
void DoWin(int Order)
{
sound(1500);delay(100);
sound(0); delay(50);
sound(800); delay(100);
sound(0); delay(50);
sound(1500);delay(100);
sound(0); delay(50);
sound(800); delay(100);
sound(0); delay(50);
nosound();
textcolor(RED+BLINK);
gotoxy(25,20);
if(Order==CHESS1)
cputs("PLAYER1 WIN!");
else
cputs("PLAYER2 WIN!");
gotoxy(25,21);
cputs("\n");
getch();
}
/*走棋*/
int ChessGo(int Order,struct point Cursor)
{
/*判断交叉点上有无棋子*/
if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL)
{
/*若没有棋子, 则可以落子*/
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
textcolor(LIGHTBLUE);
putch(Order);
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
gChessBoard[Cursor.x][Cursor.y]=Order;
return TRUE;
}
else
return FALSE;
}
/*判断当前行棋方落子后是否赢棋*/
int JudgeWin(int Order,struct point Cursor)
{
int i;
for(i=0;i4;i++)
/*判断在指定方向上是否有连续5个行棋方的棋子*/
if(JudgeWinLine(Order,Cursor,i))
return TRUE;
return FALSE;
}
/*判断在指定方向上是否有连续5个行棋方的棋子*/
int JudgeWinLine(int Order,struct point Cursor,int direction)
{
int i;
struct point pos,dpos;
const int testnum = 5;
int count;
switch(direction)
{
case 0:/*在水平方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y;
dpos.x=1;
dpos.y=0;
break;
case 1:/*在垂直方向*/
pos.x=Cursor.x;
pos.y=Cursor.y-(testnum-1);
dpos.x=0;
dpos.y=1;
break;
case 2:/*在左下至右上的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y+(testnum-1);
dpos.x=1;
dpos.y=-1;
break;
case 3:/*在左上至右下的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y-(testnum-1);
dpos.x=1;
dpos.y=1;
break;
}
count=0;
for(i=0;itestnum*2+1;i++)/*????????itestnum*2-1*/
{
if(pos.x=0pos.x=18pos.y=0pos.y=18)
{
if(gChessBoard[pos.x][pos.y]==Order)
{
count++;
if(count=testnum)
return TRUE;
}
else
count=0;
}
pos.x+=dpos.x;
pos.y+=dpos.y;
}
return FALSE;
}
/*移动光标*/
void MoveCursor(int Order,int press)
{
switch(press)
{
case PLAY1UP:
if(Order==CHESS1gCursor.y0)
gCursor.y--;
break;
case PLAY1DOWN:
if(Order==CHESS1gCursor.y18)
gCursor.y++;
break;
case PLAY1LEFT:
if(Order==CHESS1gCursor.x0)
gCursor.x--;
break;
case PLAY1RIGHT:
if(Order==CHESS1gCursor.x18)
gCursor.x++;
break;
case PLAY2UP:
if(Order==CHESS2gCursor.y0)
gCursor.y--;
break;
case PLAY2DOWN:
if(Order==CHESS2gCursor.y18)
gCursor.y++;
break;
case PLAY2LEFT:
if(Order==CHESS2gCursor.x0)
gCursor.x--;
break;
case PLAY2RIGHT:
if(Order==CHESS2gCursor.x18)
gCursor.x++;
break;
}
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*游戏结束处理*/
void EndGame(void)
{
textmode(C80);
}
/*显示当前行棋方*/
void ShowOrderMsg(int Order)
{
gotoxy(6,MAPYOFT+20);
textcolor(LIGHTRED);
if(Order==CHESS1)
cputs("Player1 go!");
else
cputs("Player2 go!");
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*落子正确处理*/
void DoOK(void)
{
sound(500);
delay(70);
sound(600);
delay(50);
sound(1000);
delay(100);
nosound();
}
/*检查用户的按键类别*/
int CheckKey(int press)
{
if(press==ESCAPE)
return KEYEXIT;/*是退出键*/
else
if
( ( press==PLAY1DO gPlayOrder==CHESS1) ||
( press==PLAY2DO gPlayOrder==CHESS2)
)
return KEYFALLCHESS;/*是落子键*/
else
if
( press==PLAY1UP || press==PLAY1DOWN ||
press==PLAY1LEFT || press==PLAY1RIGHT ||
press==PLAY2UP || press==PLAY2DOWN ||
press==PLAY2LEFT || press==PLAY2RIGHT
)
return KEYMOVECURSOR;/*是光标移动键*/
else
return KEYINVALID;/*按键无效*/
}
用C语言编写一个五子棋的游戏程序
**********************************************************/
/* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */
#include stdio.h
#include bios.h
#include ctype.h
#include conio.h
#include dos.h
/**********************************************************/
/* 定义符号常量 */
/*定义画棋盘所需的制表符*/
#define CROSSRU 0xbf /*右上角点*/
#define CROSSLU 0xda /*左上角点*/
#define CROSSLD 0xc0 /*左下角点*/
#define CROSSRD 0xd9 /*右下角点*/
#define CROSSL 0xc3 /*左边*/
#define CROSSR 0xb4 /*右边*/
#define CROSSU 0xc2 /*上边*/
#define CROSSD 0xc1 /*下边*/
#define CROSS 0xc5 /*十字交叉点*/
/*定义棋盘左上角点在屏幕上的位置*/
#define MAPXOFT 5
#define MAPYOFT 2
/*定义1号玩家的操作键键码*/
#define PLAY1UP 0x1157/*上移--'W'*/
#define PLAY1DOWN 0x1f53/*下移--'S'*/
#define PLAY1LEFT 0x1e41/*左移--'A'*/
#define PLAY1RIGHT 0x2044/*右移--'D'*/
#define PLAY1DO 0x3920/*落子--空格键*/
/*定义2号玩家的操作键键码*/
#define PLAY2UP 0x4800/*上移--方向键up*/
#define PLAY2DOWN 0x5000/*下移--方向键down*/
#define PLAY2LEFT 0x4b00/*左移--方向键left*/
#define PLAY2RIGHT 0x4d00/*右移--方向键right*/
#define PLAY2DO 0x1c0d/*落子--回车键Enter*/
/*若想在游戏中途退出, 可按 Esc 键*/
#define ESCAPE 0x011b
/*定义棋盘上交叉点的状态, 即该点有无棋子 */
/*若有棋子, 还应能指出是哪个玩家的棋子 */
#define CHESSNULL 0 //没有棋子
#define CHESS1 'O'//一号玩家的棋子
#define CHESS2 'X'//二号玩家的棋子
/*定义按键类别*/
#define KEYEXIT 0/*退出键*/
#define KEYFALLCHESS 1/*落子键*/
#define KEYMOVECURSOR 2/*光标移动键*/
#define KEYINVALID 3/*无效键*/
/*定义符号常量: 真, 假 --- 真为1, 假为0 */
#define TRUE 1
#define FALSE 0
/**********************************************************/
/* 定义数据结构 */
/*棋盘交叉点坐标的数据结构*/
struct point
{
int x,y;
};
/**********************************************************/
/*自定义函数原型说明 */
void Init(void);
int GetKey(void);
int CheckKey(int press);
int ChangeOrder(void);
int ChessGo(int Order,struct point Cursor);
void DoError(void);
void DoOK(void);
void DoWin(int Order);
void MoveCursor(int Order,int press);
void DrawCross(int x,int y);
void DrawMap(void);
int JudgeWin(int Order,struct point Cursor);
int JudgeWinLine(int Order,struct point Cursor,int direction);
void ShowOrderMsg(int Order);
void EndGame(void);
/**********************************************************/
/**********************************************************/
/* 定义全局变量 */
int gPlayOrder; /*指示当前行棋方 */
struct point gCursor; /*光标在棋盘上的位置 */
char gChessBoard[19][19];/*用于记录棋盘上各点的状态*/
/**********************************************************/
/**********************************************************/
/*主函数*/
void main()
{
int press;
int bOutWhile=FALSE;/*退出循环标志*/
Init();/*初始化图象,数据*/
while(1)
{
press=GetKey();/*获取用户的按键值*/
switch(CheckKey(press))/*判断按键类别*/
{
/*是退出键*/
case KEYEXIT:
clrscr();/*清屏*/
bOutWhile = TRUE;
break;
/*是落子键*/
case KEYFALLCHESS:
if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/
DoError();/*落子错误*/
else
{
DoOK();/*落子正确*/
/*如果当前行棋方赢棋*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile = TRUE;/*退出循环标志置为真*/
}
/*否则*/
else
/*交换行棋方*/
ChangeOrder();
}
break;
/*是光标移动键*/
case KEYMOVECURSOR:
MoveCursor(gPlayOrder,press);
break;
/*是无效键*/
case KEYINVALID:
break;
}
if(bOutWhile==TRUE)
break;
}
/*游戏结束*/
EndGame();
}
/**********************************************************/
/*界面初始化,数据初始化*/
void Init(void)
{
int i,j;
char *Msg[]=
{
"Player1 key:",
" UP----w",
" DOWN--s",
" LEFT--a",
" RIGHT-d",
" DO----space",
"",
"Player2 key:",
" UP----up",
" DOWN--down",
" LEFT--left",
" RIGHT-right",
" DO----ENTER",
"",
"exit game:",
" ESC",
NULL,
};
/*先手方为1号玩家*/
gPlayOrder = CHESS1;
/*棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/
for(i=0;i19;i++)
for(j=0;j19;j++)
gChessBoard[i][j]=CHESSNULL;
/*光标初始位置*/
gCursor.x=gCursor.y=0;
/*画棋盘*/
textmode(C40);
DrawMap();
/*显示操作键说明*/
i=0;
textcolor(BROWN);
while(Msg[i]!=NULL)
{
gotoxy(25,3+i);
cputs(Msg[i]);
i++;
}
/*显示当前行棋方*/
ShowOrderMsg(gPlayOrder);
/*光标移至棋盘的左上角点处*/
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*画棋盘*/
void DrawMap(void)
{
int i,j;
clrscr();
for(i=0;i19;i++)
for(j=0;j19;j++)
DrawCross(i,j);
}
/*画棋盘上的交叉点*/
void DrawCross(int x,int y)
{
gotoxy(x+MAPXOFT,y+MAPYOFT);
/*交叉点上是一号玩家的棋子*/
if(gChessBoard[x][y]==CHESS1)
{
textcolor(LIGHTBLUE);
putch(CHESS1);
return;
}
/*交叉点上是二号玩家的棋子*/
if(gChessBoard[x][y]==CHESS2)
{
textcolor(LIGHTBLUE);
putch(CHESS2);
return;
}
textcolor(GREEN);
/*左上角交叉点*/
if(x==0y==0)
{
putch(CROSSLU);
return;
}
/*左下角交叉点*/
if(x==0y==18)
{
putch(CROSSLD);
return;
}
/*右上角交叉点*/
if(x==18y==0)
{
putch(CROSSRU);
return;
}
/*右下角交叉点*/
if(x==18y==18)
{
putch(CROSSRD);
return;
}
/*左边界交叉点*/
if(x==0)
{
putch(CROSSL);
return;
}
/*右边界交叉点*/
if(x==18)
{
putch(CROSSR);
return;
}
/*上边界交叉点*/
if(y==0)
{
putch(CROSSU);
return;
}
/*下边界交叉点*/
if(y==18)
{
putch(CROSSD);
return;
}
/*棋盘中间的交叉点*/
putch(CROSS);
}
/*交换行棋方*/
int ChangeOrder(void)
{
if(gPlayOrder==CHESS1)
gPlayOrder=CHESS2;
else
gPlayOrder=CHESS1;
return(gPlayOrder);
}
/*获取按键值*/
int GetKey(void)
{
char lowbyte;
int press;
while (bioskey(1) == 0)
;/*如果用户没有按键,空循环*/
press=bioskey(0);
lowbyte=press0xff;
press=press0xff00 + toupper(lowbyte);
return(press);
}
/*落子错误处理*/
void DoError(void)
{
sound(1200);
delay(50);
nosound();
}
/*赢棋处理*/
void DoWin(int Order)
{
sound(1500);delay(100);
sound(0); delay(50);
sound(800); delay(100);
sound(0); delay(50);
sound(1500);delay(100);
sound(0); delay(50);
sound(800); delay(100);
sound(0); delay(50);
nosound();
textcolor(RED+BLINK);
gotoxy(25,20);
if(Order==CHESS1)
cputs("PLAYER1 WIN!");
else
cputs("PLAYER2 WIN!");
gotoxy(25,21);
cputs(" \\^+^/");
getch();
}
/*走棋*/
int ChessGo(int Order,struct point Cursor)
{
/*判断交叉点上有无棋子*/
if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL)
{
/*若没有棋子, 则可以落子*/
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
textcolor(LIGHTBLUE);
putch(Order);
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
gChessBoard[Cursor.x][Cursor.y]=Order;
return TRUE;
}
else
return FALSE;
}
/*判断当前行棋方落子后是否赢棋*/
int JudgeWin(int Order,struct point Cursor)
{
int i;
for(i=0;i4;i++)
/*判断在指定方向上是否有连续5个行棋方的棋子*/
if(JudgeWinLine(Order,Cursor,i))
return TRUE;
return FALSE;
}
/*判断在指定方向上是否有连续5个行棋方的棋子*/
int JudgeWinLine(int Order,struct point Cursor,int direction)
{
int i;
struct point pos,dpos;
const int testnum = 5;
int count;
switch(direction)
{
case 0:/*在水平方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y;
dpos.x=1;
dpos.y=0;
break;
case 1:/*在垂直方向*/
pos.x=Cursor.x;
pos.y=Cursor.y-(testnum-1);
dpos.x=0;
dpos.y=1;
break;
case 2:/*在左下至右上的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y+(testnum-1);
dpos.x=1;
dpos.y=-1;
break;
case 3:/*在左上至右下的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y-(testnum-1);
dpos.x=1;
dpos.y=1;
break;
}
count=0;
for(i=0;itestnum*2+1;i++)
{
if(pos.x=0pos.x=18pos.y=0pos.y=18)
{
if(gChessBoard[pos.x][pos.y]==Order)
{
count++;
if(count=testnum)
return TRUE;
}
else
count=0;
}
pos.x+=dpos.x;
pos.y+=dpos.y;
}
return FALSE;
}
/*移动光标*/
void MoveCursor(int Order,int press)
{
switch(press)
{
case PLAY1UP:
if(Order==CHESS1gCursor.y0)
gCursor.y--;
break;
case PLAY1DOWN:
if(Order==CHESS1gCursor.y18)
gCursor.y++;
break;
case PLAY1LEFT:
if(Order==CHESS1gCursor.x0)
gCursor.x--;
break;
case PLAY1RIGHT:
if(Order==CHESS1gCursor.x18)
gCursor.x++;
break;
case PLAY2UP:
if(Order==CHESS2gCursor.y0)
gCursor.y--;
break;
case PLAY2DOWN:
if(Order==CHESS2gCursor.y18)
gCursor.y++;
break;
case PLAY2LEFT:
if(Order==CHESS2gCursor.x0)
gCursor.x--;
break;
case PLAY2RIGHT:
if(Order==CHESS2gCursor.x18)
gCursor.x++;
break;
}
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*游戏结束处理*/
void EndGame(void)
{
textmode(C80);
}
/*显示当前行棋方*/
void ShowOrderMsg(int Order)
{
gotoxy(6,MAPYOFT+20);
textcolor(LIGHTRED);
if(Order==CHESS1)
cputs("Player1 go!");
else
cputs("Player2 go!");
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*落子正确处理*/
void DoOK(void)
{
sound(500);
delay(70);
sound(600);
delay(50);
sound(1000);
delay(100);
nosound();
}
/*检查用户的按键类别*/
int CheckKey(int press)
{
if(press==ESCAPE)
return KEYEXIT;/*是退出键*/
else
if
( ( press==PLAY1DO gPlayOrder==CHESS1) ||
( press==PLAY2DO gPlayOrder==CHESS2)
)
return KEYFALLCHESS;/*是落子键*/
else
if
( press==PLAY1UP || press==PLAY1DOWN ||
press==PLAY1LEFT || press==PLAY1RIGHT ||
press==PLAY2UP || press==PLAY2DOWN ||
press==PLAY2LEFT || press==PLAY2RIGHT
)
return KEYMOVECURSOR;/*是光标移动键*/
else
return KEYINVALID;/*按键无效*/
}
C语言五子棋算法
五子棋胜负的判定,一般有一下两种算法:
1.扫描整个棋盘,分别扫描四个方向是否有5个连子。网上找了很多五子棋源码都是用此算法,这意味着每下一个棋子都要扫描一遍19×19的棋盘,复杂而且低效,代码略。
2.每下一字,从该子开始扫描其四个方向(例如:从该子的(x-4,y)坐标开始扫描横向)是否存在5个连子。此算法较为常用,而且不涉及更为复杂的数据结构。
另外,为解决扫描越界的问题,在声明棋盘棋子位置时,可声明一个(4+19+4)×(4+19+4)的棋盘,而让棋子偏移(4,4)个坐标。
算法2源代码如下:
?123456789101112131415161718192021static void IfWin(int x,int y,int color){ TCHAR win[20]; int a,b; if(stone[x][y]==1) wcscpy_s(win,_T("黑棋胜利!")); else wcscpy_s(win,_T("白棋胜利!")); for(a=x-4;a=x+4;a++)//判断横 if(stone[a][y]==colorstone[a+1][y]==colorstone[a+2][y]==colorstone[a+3][y]==colorstone[a+4][y]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(b=y-4;b=y+4;b++)//判断竖 if(stone[x][b]==colorstone[x][b+1]==colorstone[x][b+2]==colorstone[x][b+3]==colorstone[x][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y-4;a=x+4;a++,b++)//判断右斜 if(stone[a][b]==colorstone[a+1][b+1]==colorstone[a+2][b+2]==colorstone[a+3][b+3]==colorstone[a+4][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y+4;a=x+4;a++,b--)//判断左斜 if(stone[a][b]==colorstone[a+1][b-1]==colorstone[a+2][b-2]==colorstone[a+3][b-3]==colorstone[a+4][b-4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;}}