五子棋c#实训报告
五子棋比赛规则及流程

五子棋比赛规则及流程五子棋是一种源于中国的策略棋类游戏,它简单易学,规则明确,适合任何年龄段的人都能够参与,因此在世界范围内都很受欢迎。
下面将详细介绍五子棋比赛的规则和流程。
比赛规则:1.棋盘:五子棋棋盘是一个15×15的方格,每个格子可以放置一个棋子。
2.棋子:比赛双方使用不同的棋子进行对局,一方使用黑色棋子,另一方使用白色棋子。
3.先手:比赛开始时由先手方下第一子,然后双方轮流下棋,每次只能下一子。
4.胜负条件:比赛中,任何一方先在一个横线、竖线或者对角线上形成连续的五个自己颜色的棋子即可获胜。
5.和棋判定:如果双方都未达到胜利条件,并且棋盘已经下满,比赛则以和棋结束。
比赛流程:1.准备:比赛前,各参赛选手确认对手身份并选定执黑先手或执白后手。
同时,棋手可以调整棋盘摆放位置。
2.开局:先手方在棋盘中任意位置下一枚自己颜色的棋子。
然后双方轮流下棋,每次只能下一子。
3.下棋:每次轮到自己下棋时,选手需要轮流选择一个空位下棋,可以选择落子的位置是棋盘上的任何一个尚未放下棋子的空位。
注意,一旦棋子落下,就不能再移动或更换位置。
4.判断胜负:每当有一方下棋之后,裁判需立即检查比赛状态,看是否满足胜利条件。
如果有一方达到胜利条件,比赛结束,该选手获胜。
如果棋盘已满且没有一方达到胜利条件,则比赛以和棋结束。
比赛结果由裁判宣布。
5.记录:裁判在比赛过程中会记录比赛双方每一步的棋子位置,并在比赛结束后将棋盘摆放状况以及结果公布给所有参赛选手及观众。
6.庆祝:胜利一方可以适当表达喜悦之情,与对方及观众互动庆祝。
五子棋比赛规则和流程明确简单,易于操作,使得整个比赛过程有序规范并能有效解决比赛中的争议。
参与者可以根据规则进行策略和技巧上的思考,并随时检查比赛状态以判断自己的优势。
无论是专业棋手还是普通玩家,都能在五子棋比赛中体验到策略比拼和智慧之乐。
c 课程设计报告五子棋

c 课程设计报告五子棋C++面向对象课程设计报告院(系):专业: 学生姓名: ,,班级:,,,学号:题目: 五子连珠棋 ,,,,,,,,,起迄日期: 2010-12-20,,,, ,,,,, 设计地点:指导教师:完成日期: 2010 年 12 月31 日课程设计报告内容一、需求分析1( 选做此课题目的五子棋游戏是一历史悠久,对抗性强,技巧性高的棋类游戏。
而且我对五子棋有着独特的爱好,希望自己也可以编写出一款可以实现人机对战的五子棋游戏。
把自己的思想付给电脑,让自己有些成就感,给自己继续努力的动力。
借此次课程设计的机会,把想法变成现实。
而且五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
所以此次c++课程设计选择五子棋这个题目。
2( 程序所实现的功能通过给电脑赋予人工智能,利用电脑运算速度快的特点,结合五子棋的游戏规则,给电脑设定固定的扫描方式,设定权值,使电脑能够选择最合适的落子点,然后调用加载已做好的棋盘棋子图像,最终实现简单的人机对弈。
3(该游戏为普通玩家使用,只要连成五子即获胜,没有禁手、RIF(国际连珠连盟)正式规则、“Yamaguchi”、”Tarannikov”、“Taraguchi”等规则。
二、设计内容1( 根据所选题目,给出模块图主界面开始游戏重新开始游戏游戏结束初始化棋盘初始化棋盘结束界面落子判断输赢2( 画出主程序及其主要模块的流程图游戏开始初始化棋盘加载棋盘图片1点鼠标左键落子加载棋子图片到棋盘扫描棋盘,根据预设权值,选择最佳地点落子否五子连珠,加载棋子图片到棋盘是否五子连转1 珠,是用红色显示游戏结束3( 编写程序代码加载位图(棋盘和棋子):m_board->m_hObject = (HBITMAP)::LoadImage (NULL,"checkerboard.bmp",IMAGE_BITMAP,320,320,LR_LOADFROMFILE); m_white->m_hObject = (HBITMAP)::LoadImage(NULL,"bai.bmp",IMAGE_BITMAP,20,20,LR_LOADFROMFILE);m_black->m_hObject = (HBITMAP)::LoadImage(NULL,"hei.bmp",IMAGE_BITMAP,20,20,LR_LOADFROMFILE);m_temp->m_hObject = (HBITMAP)::LoadImage(NULL,"mask1.bmp",IMAGE_BITMAP,20,20,LR_LOADFROMFILE);m_red->m_hObject=(HBITMAP)::LoadImage(NULL,"dred.bmp",IMAGE_BITMAP,20,20,LR_LOADFROMFILE); 响应左键:LButtonDown(UINT nFlags, CPoint point) { int m ,n;CDC thmem1 ;CClientDC dc(this);thmem1.CreateCompatibleDC(&dc);int curx = point.y;int cury = point.x;m =int((curx-5)/20);n = int((cury-15)/20);}没有五子连珠时简单显示棋子:显示白色棋子: if(board[i][j]==0){ thmem2.SelectObject (m_temp);dc.BitBlt(j*20+15,i*20+5,20,20,&thmem2,0,0,MERGEPAINT); thmem2.SelectObject (m_black);dc.BitBlt (j*20+15,i*20+5,20,20,&thmem2,0,0,SRCAND);m_byColour = white ;}显示黑色棋子: if(board[i][j] == 1){ thmem2.SelectObject (m_temp);dc.BitBlt(j*20+15,i*20+5,20,20,&thmem2,0,0,MERGEPAINT); thmem2.SelectObject (m_white);dc.BitBlt (j*20+15,i*20+5,20,20,&thmem2,0,0,SRCAND);m_byColour = black;}五子连珠时红色显示棋子:人赢时: if(ptable[ii][jj][j] == true){ thmem2.SelectObject(m_temp);dc.BitBlt(jj*20+15,ii*20+5,20,20,&thmem2,0,0,MERGEPAINT); thmem2.SelectObject(m_red);dc.BitBlt(jj*20+15,ii*20+5,20,20,&thmem2,0,0,SRCAND); } // MessageBox("你赢了");计算机赢时: if(ctable[ii][jj][j] == true){ thmem2.SelectObject (m_temp);dc.BitBlt(jj*20+15,ii*20+5,20,20,&thmem2,0,0,MERGEPAINT); thmem2.SelectObject (m_red);dc.BitBlt(jj*20+15,ii*20+5,20,20,&thmem2,0,0,SRCAND);}电脑扫描棋盘: for(i = 0 ; i<15; i++)for(j= 0 ;j <15 ;j++)board[i][j] = 2; // 初始化棋盘数组for(i = 0 ; i <15 ; i++) //对列进行隔行扫描,for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[j+k][i][count] = true;ctable[j+k][i][count] = true;} count ++;}for(i = 0 ; i <15 ; i++) //对行进行隔行扫描for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[i][j+k][count] = true;ctable[i][j+k][count] = true;}count ++;}for(i = 0 ; i <11; i++) //对交叉的情况,东南,西北走向,进行扫描for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[j+k][i+k][count] = true;ctable[j+k][i+k][count] = true;}count ++;}for(i = 0 ; i <11 ; i++) //对交叉的情况,东北,西南走向,进行扫描for(j=14 ; j >= 4 ; j--){for( k = 0 ; k <5 ;k++){ptable[j-k][i+k][count] = true;ctable[j-k][i+k][count] = true;}count ++;}Start:void CMyDlg::Onstart() {MessageBox("请落子");m_byColour = black;}Restart:再次初始化棋盘,函数类似于扫描{for(i = 0 ; i<15; i++)for(j= 0 ;j <15 ;j++)board[i][j] = 2;for(i = 0 ; i <15 ; i++)for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[j+k][i][count] = true; ctable[j+k][i][count] = true; }count ++;}for(i = 0 ; i <15 ; i++)for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[i][j+k][count] = true;ctable[i][j+k][count] = true;}count ++;}for(i = 0 ; i <11; i++)for(j=0 ; j <11 ; j++){for( k = 0 ; k <5 ;k++){ptable[j+k][i+k][count] = true;ctable[j+k][i+k][count] = true;}count ++;}for(i = 0 ; i <11 ; i++)for(j=14 ; j >= 4 ; j--){ for( k = 0 ; k <5 ;k++){ ptable[j-k][i+k][count] = true;ctable[j-k][i+k][count] = true; }count ++; }三、调试分析1( 实际完成的情况说明能够判断胜负,没下一子,都要进行胜负判断,赋予电脑人工智能,玩家通过点击鼠标左键落子,电脑会根据预设的方式扫描,计算每一点的权值,从而找到最佳落子点,实现人机对弈。
五子棋

历史
阵法
规则
开局
兵法
人生如棋
好处
棋局
建工11-5班 黄斌,王文权,汪驰奡,许磊, 庞剑威,俞意郎
称谓
五子棋,日文亦有“连五子、五子连、串珠、五目、 五目碰、五格、五石、五法、五联、京棋”等多种称谓, 英文则称之为“FIR (Five In A Row的缩写)、Gomoku(日 语“五目”的罗马拼音)、Gobang、connect 5、morphion”。捷克语piskvorky,韩语omok…… 许多国家的人对五子棋都有不同的爱称,例如,韩国 人把五子棋称为“情侣棋”,暗示情人之间下五子棋有利 于增加情感的交流;欧洲人称其为“绅士棋”,代表下五 子棋的君子风度胜似绅士;日本人则称其为“中老年棋”, 说明五子棋适合中老年人的生理特点和思维方式;美国人 喜欢将五子棋称为“商业棋”,也就是说,商人谈生意时 可边下棋边谈生意,棋下完了生意也谈成了。
攻不忘守,守不忘攻。有句话叫“最强的 防守就是进攻”,防守别人棋的时候仔细 看清局势,是不是有既能防守住对方又可 以进攻的点。以守待攻,在对方狂攻一阵 却无胜棋后,你防守的棋是否形成了外围 的攻势?在安全的前提下,防守对方的棋 最好不要太消极,等他攻完,就可以利用 防守时形成的攻势轻松收拾对方 。
规则
首先于1899年规定黑白双方均禁止走“双三”。堵住了双 方通往胜利可能性的一条重要渠道。这样增加了难度,提 高了技术性。还规定了多局制决定胜负,来使对弈双方获 得比较均等的获胜机会。 众所周知,用这种方法不能解决多大问题,先走方的优势 无法铲除。五子棋连五为胜,先走一方优势很大。五子棋 没有吃子,也不比占地大小,无法从这两方面给后走方一 些补偿。日本人从双方禁手受到启发,试着给先走的黑方 设立禁手。先后于1903年规定“双三”为黑方禁手;1916 年规定“长连”为黑方禁手;1931年规定“双四”为黑方 禁手。堵住几条黑方获胜的可能性渠道还不够,又给白方 开辟了一条新的获胜渠道,就是规定黑方被迫走禁手也判 负,意味着白方可用强迫黑方走出禁手而获胜,这就是 “追下取胜”。
五子棋是起源于中国古代的传统黑白棋种之一03

五子棋是起源于中国古代的传统黑白棋种之一。
现代五子棋日文称之为“ 连珠” ,英译为“Renju” ,英文称之为“Gobang” 或“FIR”(Five in a Row 的缩写 ) ,亦有“ 连五子” 、“ 五子连” 、“ 串珠” 、“ 五目” 、“ 五目碰” 、“ 五格” 等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“ 短、平、快” ,又有古典哲学的高深学问“ 阴阳易理” ;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“ 场” 的概念,亦有“ 点” 的连接。
它是中西文化的交流点,是古今哲理的结晶。
五子棋起源于古代中国,发展于日本,风靡于欧洲。
对于它与围棋的关系有两种说法,一说早于围棋,早在“ 尧造围棋” 之前,民间就已有五子棋游戏;一说源于围棋,是围棋发展的一个分支。
在中国的文化里,倍受人们的青睐。
古代的五子棋的棋具与围棋相同,纵横各十七道。
五子棋大约随围棋一起在我国南北朝时先后传入朝鲜、日本等地。
据日本史料文献介绍,中国古代的五子棋是经由高丽 ( 朝鲜 ) ,于 1688 年至 1704 年的日本元禄时代传到日本的。
到日本明治 32 年 ( 公元 1899 年 ) ,经过公开征名,“ 连珠” 这一名称才被正式确定下来,取意于“ 日月如合壁,五星如连珠” 。
从此,连珠活动经过了不断的改良,主要是规则的变化 ( 即对执黑棋一方的限制 ) ,例如, 1899 年规定,禁止黑白双方走“ 双三” ; 1903 年规定,只禁止黑方走“ 双三” ; 1912 年规定,黑方被迫走“ 双三” 亦算输; 1916 年规定,黑方不许走“ 长连” ; 1918 年规定,黑方不许走“ 四、三、三” ; 1931 年规定,黑方不许走“ 双四” ,并规定将19×19 的围棋盘改为15×15 的连珠专用棋盘。
【报告】c五子棋实验报告

【关键字】报告c五子棋实验报告篇一:五子棋对战实验报告实验项目五子棋网络对战和聊天实验日期XX0406实验报告要求:一、实验目的:学习和使用socket编程,熟练软件开发二、实验原理:使用socket进行网络通信,java作为编程语言三、实验要求:编写五子棋程序可以实现联机网络对战,并且可以进行聊天四、实验步骤、结果(程序+注释+截图)及分析:首先拟定编程语言与开发方案,选择java语言,考虑到java可以跨平台运行,然后决定把这个程序拆分为客户端、服务器两个部分,每个部分再分成5个小的部分实现不同功能。
1、然后考虑使用java的swing包,创建ClientChessPanel类负责棋盘部分,包括判断输赢,使用数组chesses[i][j]记录棋盘上棋子的分布,对数组进行不同的赋值表示网格节点上无棋、黑棋、白棋;使用playChessHandler作为鼠标单击事件,单击事件调用Clientskt中的函数传送棋子坐标以及输赢信息。
drawChess函数画棋子,drawGrids画网格,gameOver判断棋盘棋子分布,输赢情况。
importjavax.swing.*;importjava.awt.*;;importChatOneToOneClient.Clientskt;classClientChessPanel extends JPanel{private static final long serialVersionUID = 1L;private int space=20; //网格间的距离private int grids=30; //棋盘的网格数private int radius=space/2; //棋的半径Clientsktskt;//当chesses[i][j]=0,表示网格节点(i,j)上无棋//当chesses[i][j]=1,表示网格节点(i,j)上放白棋//当chesses[i][j]=2,表示网格节点(i,j)上放黑棋privateint[][] chesses=new int[grids+1][grids+1];private intcurrColor=1; //当前棋的颜色privateMouseListenerplayChessHandler=new MouseAdapter(){public void mouseClicked(MouseEvent e){if(skt.reMouseGo()){int x=e.getX();int y=e.getY();//放一颗棋子if(x=0 && y=0)if(chesses[round(x)][round(y)]==0){chesses[round(x)][round(y)]=currColor;repaint(); //刷新图形skt.dataout("x:"+String.valueOf(round(x)));skt.dataout("y:"+String.valueOf(round(y)));skt.setMouseGo(false);if(gameOver(currColor)){skt.dataout("g:你输了");ClientMyDialog(skt.chat,"你赢了");;}currColor=currColor==1?2:1; //切换棋子的颜色}}}};public int round(float a){ //获得接近a的网格节点坐标float f=a/space;returnMath.round(f);}publicClientChessPanel(intspace,intgrids,Clientsktskt){ this.space=space;this.grids=grids;this.radius=space/2;this.skt=skt;setBackground(Color.BLUE);setSize(space*grids,space*grids);addMouseListener(playChessHandler);startChess();}public void startChess(){clearGrids(); //清空棋盘currColor=1;repaint(); //刷新图形private void clearGrids(){for(inti=0;i for(int j=0;j chesses[i][j]=0;}//画一颗棋子private void drawChess(Graphics g,intx,inty,int color){g.setColor(color==1?Color.GREEN:Color.BLACK);g.fillOval(x*space-radius,y*space-radius,radius*2,radius*2);}//画网格private void drawGrids(Graphics g){g.setColor(Color.DARK_GRAY);for(inti=0;i g.drawLine(0,i*space,grids*space,i*space);g.drawLine(i*space,0,i*space,grids*space);}}//接收对方下的棋坐标public void paintChess(intx,int y){if(x=0 && y=0){if(chesses[x][y]==0){chesses[x][y]=currColor;currColor=currColor==1?2:1; //切换棋子的颜色skt.setMouseGo(false);skt.setMouseGo(true);repaint(); //刷新图形}}}//判断游戏是否结束publicbooleangameOver(intgameOver){int five=0;//用于判断是否有连续5个子for(inti=0;i for(int j=0;j if(chesses[i][j]==gameOver){five++;for(in(本文来自:小草范文网:c五子棋实验报告)t k=1;k if(chesses[i][j+k]==gameOver){five++;if(five==5){return true;}else{five=1;k=5;}}for(int k=1;k if(chesses[i+k][j]==gameOver){ five++;if(five==5){return true;}}else{five=1;k=5;}}for(int k=1;k if(chesses[i+k][j+k]==gameOver){ five++;if(five==5){return true;}}else{five=1;k=5;}}for(int k=1;k4;k++){//左斜向比较if(chesses[i+k][j-k]==gameOver){five++;if(five==5){return true;}}else{five=1;}}}}five=0;}return false;}public void paintComponent(Graphics g){ //覆盖paintComponent()方法super.paintComponent(g); //必须先调用父类的方法drawGrids(g); //画网格for(inti=0;i for(int j=0;j if(chesses[i][j]!=0)drawChess(g,i,j,chesses[i][j]); //画棋子}}2、ClientComponentPopupMenu类主要负责聊天的部分,使用JTextField并且对其添加单击事件以及鼠标事件,可以实现文本的剪贴、复制粘贴等功能。
C++课程设计--五子棋游戏

C++课程设计--五子棋游戏课程设计说明书五子棋游戏The Game of Gobang学院名称:机械工程学院专业班级:测控10xx 学生姓名:江x 指导教师姓名:张xx 指导教师职称:副教授2012年6月目录第一章需求分析 (7)1.1系统概述 (7)1.1.1概述: (7)1.2系统运行环境 (7)1.2.1运行环境 (7)1.3功能需求描述 (7)1.3.1功能需求 (7)第二章总体设计 (8)2.1开发与设计的总体思想 (8)2.1.1总体设计思路 (8)2.1.2屏幕的组成 (9)2.1.3形状的组成 (9)2.1.4形状的统一 (10)第三章概要设计 (10)3.1系统流程图 (10)3.2 软件功能模块 (12)3.3 系统功能模块 (13)第四章详细设计 (13)4.1.界面的设计 (13)4.1.1总体界面的设计 (13)4.1.2界面棋子的设计 (13)4.2.显示界面的准备 (15)4.2.1在窗体类中添加存放黑白棋两维数组和背景棋盘、黑棋、白棋位图对象 (15)4.2.2 在窗体构造函数中初始化wb,装入棋盘、黑棋、白棋位图 (15)4.3. 显示棋盘和棋子代码 (15)4.4. 轮流下子代码 (16)4.5. 判断输赢 (19)4.5.1判断是否白棋胜代码 (19)4.5.2判断是否黑棋胜代码 (20)4.5.3判断是否平局代码 (21)4.6. 悔棋 (21)4.7. 重新开始 (22)4.8. 背景音乐 (23)4.9. 保存读取游戏文件 (23)4.9.1保存文件: (24)4.9.2读取文件: (25)第五章测试分析 (26)结论和心得体会 (27)致谢 (28)参考文献: (29)课程设计任务书一、课程设计目的课程设计是工科各专业的主要实践性教学环节之一,是围绕一门主要基础课或专业课,运用所学课程的知识,结合实际应用设计而进行的一次综合分析设计能力的训练。
课程设计旨在培养学生在本课程范围内,初步掌握解决实际应用问题时所应具有的查阅资料、综合运用所学知识的能力,为课程设计及今后从事专业工作打下基础。
c语言五子棋(字符版+AI)

for (qi=1;qipan[playx][playy+qi]!=qizi&&qi<5;qi++)
{
if (qipan[playx][playy+qi]==qz)qh2++;
if (qipan[playx][playy+qi]!='*'&&qipan[playx][playy+qi]!='#')space2++;
{
qipan[playx+qp2+1][playy+qp2+1]=qizi;
stop=true;
return true;
}
}
}
if (stop==false )
{
for (qi=1;qipan[playx+qi][playy-qi]==qz;qi++)
for (qi=1;qipan[playx+qi][playy+qi]==qz;qi++)
qp2++;
if (qp1+qp2+1>=3)//左斜挡棋
{
if (qipan[playx-qp1-1][playy-qp1-1]!='*'&&qipan[playx-qp1-1][playy-qp1-1]!='#'&&(playx-qp1-1>0&&playx-qp1-1<=15)&&(playy-qp1-1>0&&playy-qp1-1<=15))
五子棋基本知识ppt课件

目 录
• 五子棋概述 • 五子棋的基本技巧 • 五子棋的战术应用 • 五子棋的定式与布局 • 五子棋的心理学与哲学思考 • 五子棋的实战演练与案例分析
01
五子棋概述
五子棋的起源与发展
01
02
03
起源
五子棋,又称为连珠、连 五等,起源于中国的古代 黑白棋种之一。
发展
五子棋在日本得到了广泛 的发展,并形成了现代的 规则体系,成为一项国际 竞技项目。
应对对手的定式
熟悉并掌握对手常用的定式及 其变化,制定相应的应对策略
。
05
五子棋的心理学与哲学思考
心理学在五子棋中的应用
决策心理学
五子棋高手往往能在复杂局面中 迅速做出决策,这得益于他们对 决策心理学的掌握,如预期效用
理论、前景理论等。
认知心理学
五子棋对局中需要不断对局面进 行评估和预测,这需要运用认知 心理学中的知觉、记忆、思维等
意志品质培养
在艰苦的训练和比赛中,培养坚韧不 拔的意志品质,以应对各种挑战和困 难。
比赛策略制定
根据对手的特点和局面形势,制定合 理的比赛策略,如稳扎稳打、积极进 攻或灵活多变等。
06
五子棋的实战演练与案例分析
经典对局解析
01
介绍经典对局背景及双 方选手
02
详细解析对局过程,包 括布局、中盘和收官阶 段
扩张与压缩
根据局势变化,适时采取扩张 或压缩的策略。
利用先手优势
先手方应充分利用先手优势, 积极进攻或抢占要点。
定式在实战中的应用
定式活用
在实战中灵活运用定式,根据 局势变化进行调整。
定式创新
在掌握基本定式的基础上,勇 于创新,打破常规。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
九江学院实训报告实训名称:Java编程指导老师:李兴南雷波姓名:肖世明学号:***********班级:理学A1221提交日期:2015年10月20日1.实训目的:通过本实训,应达到如下目标:理解委托的概念,掌握线程之间通过委托与控件交互的方法。
理解异常处理的机制,掌握异常处理语句的用法。
理解线程的概念,掌握多线程编程的一般方法。
掌握基于TCP的应用编程技术。
2.实训题目:通过开发一款网络对战五子棋游戏,熟练掌握Java网络编程技术,亲历一个项目开发的流程3.功能描述:程序基本功能描述如下:实训项目要求使用Java编程语言,基于客户机/服务器(C/S)模式,开发一款网络对战五子棋游戏。
服务器端可以支持多玩家同时在线游戏。
玩家可以通过客户端登陆到服务器端与其它玩家进行五子棋游戏对战。
项目基本要求描述如下:1.当服务器“启动服务”之后,可以允许玩家连接服务器;当服务器“停止服务”之后,不允许玩家连接服务器。
2.玩家请求登陆时需提交用户名,在没有“满员”和“重名”的情况下,服务器允许玩家登陆;在“满员”或“重名”的情况下,服务器拒绝玩家登陆。
3.玩家登陆成功之后,进入“游戏大厅”界面,并获得其他在线玩家的信息,其他玩家也能获得该玩家的信息。
4.玩家注销登陆之后,断开与服务器的连接,并关闭“游戏大厅”界面。
5.玩家“落座”之后,进入“游戏桌”界面,并获得该桌玩家的信息。
如果有对家落座,对家也能获得该玩家落座的信息。
其他玩家也能获得该玩家的状态的改变。
6.玩家“起身”之后,进入“游戏大厅”界面。
如果有对家落座,对家也能获得该玩家起身的信息。
其他玩家也能获得该玩家的状态的改变。
7.玩家“请求开始”游戏之后,初始化“棋盘”界面,玩家进入“就绪”状态。
如果有对家也处于“就绪”状态,则开始游戏。
其他玩家也能获得该玩家的状态的改变。
8.游戏开始之后,首先黑方“行棋”,之后双方轮流行棋。
9.玩家“落子”之后,对家也能获得“棋盘”状态的改变。
如果玩家“获胜”,对家能得知自己“失败”;否则双方继续“行棋”。
10.玩家“请求和棋”之后,对家能获得其请求。
对家可以“同意和棋”,也可以“拒绝和棋”。
如果对家同意和棋,则和局;否则游戏继续进11.上述要求是本项目的基本要求,也可新增积分排行榜和保存棋局等功能。
4.设计说明:服务器功能(1)服务器提供一个五子棋的游戏厅,拥有多个游戏桌(1~100),每桌有两个座位,0代表黑方,1代表白方。
(2)服务器启动服务后,创建一个线程专门监听玩家的连接请求。
服务器一旦接受一个连接,就创建一个与玩家对应的线程,用于接受玩家信息,并提供相应的服务。
玩家退出后,其对应的线程便自动终止,并给出相应提示。
可限制玩家人数(1~300)。
客户端功能(1)客户端连接成功后,创建一个接收线程,用于接受服务器发送信息。
(2)接受的信息处理。
5.源代码(1)sever:GameTable:class GameTable{private const int None = -1;private const int Black = 0;private const int White = 1;public Player[] gamePlayer;private int[,] grid = new int[15, 15];private System.Timers.Timer timer;private int NextdotColor = 0;private ListBox listbox;Random rnd = new Random();Service service;private int NextPlayer = -1;private int gameType = 1;public GameTable(ListBox listbox){gamePlayer = new Player[2];gamePlayer[0] = new Player();gamePlayer[1] = new Player();timer = new System.Timers.Timer();timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Enabled = false;this.listbox = listbox;service = new Service(listbox);ResetGrid();public void ResetGrid(){for (int i = 0; i <= grid.GetUpperBound(0); i++){for (int j = 0; j <= grid.GetUpperBound(1); j++) {grid[i, j] = None;}}gamePlayer[0].grade = 0;gamePlayer[1].grade = 0;}public void StartTimer(){if (NextdotColor == 0){NextPlayer = 0;NextdotColor = 1;}}public void StopTimer(){}public void SetTimerLevel(int interval){gameType = interval;}private void timer_Elapsed(object sender, EventArgs e) {}public void SetDot(int i, int j, int dotColor){grid[i, j] = dotColor;service.SendToBoth(this, string.Format("SetDot,{0},{1},{2}", i, j, dotColor));if (gameType == 1){if ((i > 1 && grid[i - 1, j] == dotColor && grid[i - 2, j] == dotColor) || (i > 0 && i < grid.GetUpperBound(0) - 1 && grid[i - 1, j] == dotColor && grid[i + 1, j] == dotColor)|| (i < grid.GetUpperBound(0) - 2 && grid[i + 1, j] == dotColor && grid[i + 2, j] == dotColor)){ShowWin(dotColor);}if ((j > 1 && grid[i, j - 1] == dotColor && grid[i, j - 2] == dotColor) || (j > 0 && j < grid.GetUpperBound(1) - 1 && grid[i, j - 1] == dotColor && grid[i, j + 1] == dotColor)|| (j < grid.GetUpperBound(1) - 2 && grid[i, j + 1] == dotColor && grid[i, j + 2] == dotColor)){ShowWin(dotColor);}if ((i > 1 && j > 1 && grid[i - 1, j - 1] == dotColor && grid[i - 2, j - 2] == dotColor)|| (i > 0 && i < grid.GetUpperBound(0) - 1 && j > 0 && j <grid.GetUpperBound(1) - 1 && grid[i - 1, j - 1] == dotColor && grid[i + 1, j + 1] == dotColor) || (i < grid.GetUpperBound(0) - 2 && j < grid.GetUpperBound(1) - 2 && grid[i + 1, j + 1] == dotColor && grid[i + 2, j + 2] == dotColor)){ShowWin(dotColor);}if((i > 1 && j < grid.GetUpperBound(1) - 2 && grid[i - 1, j + 1] == dotColor && grid[i - 2, j + 2] == dotColor)|| (i > 0 && i < grid.GetUpperBound(0) - 1 && j > 0 && j <grid.GetUpperBound(1) - 1 && grid[i - 1, j + 1] == dotColor && grid[i + 1, j - 1] == dotColor) || (i < grid.GetUpperBound(0) - 2 && j > 1 && grid[i + 1, j - 1] == dotColor && grid[i + 2, j - 2] == dotColor)){ShowWin(dotColor);}}else{if ((i > 3 && grid[i - 1, j] == dotColor && grid[i - 2, j] == dotColor && grid[i - 3, j] == dotColor && grid[i - 4, j] == dotColor)|| (i > 2 && i < grid.GetUpperBound(0) - 1 && grid[i - 1, j] == dotColor && grid[i - 2, j] == dotColor && grid[i - 3, j] == dotColor && grid[i + 1, j] == dotColor) || (i > 1 && i < grid.GetUpperBound(0) - 2 && grid[i - 1, j] == dotColor && grid[i - 2, j] == dotColor && grid[i + 1, j] == dotColor && grid[i + 2, j] == dotColor) || (i > 0 && i < grid.GetUpperBound(0) - 3 && grid[i - 1, j] == dotColor && grid[i + 1, j] == dotColor && grid[i + 2, j] == dotColor && grid[i + 3, j] == dotColor) || (i < grid.GetUpperBound(0) - 4 && grid[i + 1, j] == dotColor && grid[i + 2, j] == dotColor && grid[i + 3, j] == dotColor && grid[i + 4, j] == dotColor)){ShowWin(dotColor);}if ((j > 3 && grid[i, j - 1] == dotColor && grid[i, j - 2] == dotColor && grid[i, j - 3] == dotColor && grid[i, j - 4] == dotColor)|| (j > 2 && j < grid.GetUpperBound(1) - 1 && grid[i, j - 1] == dotColor && grid[i, j - 2] == dotColor && grid[i, j - 3] == dotColor && grid[i, j + 1] == dotColor) || (j > 1 && j < grid.GetUpperBound(1) - 2 && grid[i, j - 1] == dotColor && grid[i, j - 2] == dotColor && grid[i, j + 1] == dotColor && grid[i, j + 2] == dotColor) || (j > 0 && j < grid.GetUpperBound(1) - 3 && grid[i, j - 1] == dotColor && grid[i, j + 1] == dotColor && grid[i, j + 2] == dotColor && grid[i, j + 3] == dotColor) || (j < grid.GetUpperBound(1) - 4 && grid[i, j + 1] == dotColor && grid[i, j + 2] == dotColor && grid[i, j + 3] == dotColor && grid[i, j + 4] == dotColor)){ShowWin(dotColor);}if ((i > 3 && j > 3 && grid[i - 1, j - 1] == dotColor && grid[i - 2, j - 2] == dotColor && grid[i - 3, j - 3] == dotColor && grid[i - 4, j - 4] == dotColor)|| (i > 2 && i < grid.GetUpperBound(0) - 1 && j > 2 && j <grid.GetUpperBound(1) - 1 && grid[i - 1, j - 1] == dotColor && grid[i - 2, j - 2] == dotColor && grid[i - 3, j - 3] == dotColor && grid[i + 1, j + 1] == dotColor)|| (i > 1 && i < grid.GetUpperBound(0) - 2 && j > 1 && j <grid.GetUpperBound(1) - 2 && grid[i - 1, j - 1] == dotColor && grid[i - 2, j - 2] == dotColor && grid[i + 1, j + 1] == dotColor && grid[i + 2, j + 2] == dotColor)|| (i > 0 && i < grid.GetUpperBound(0) - 3 && j > 0 && j <grid.GetUpperBound(1) - 3 && grid[i - 1, j - 1] == dotColor && grid[i + 1, j + 1] == dotColor && grid[i + 2, j + 2] == dotColor && grid[i + 3, j + 3] == dotColor)|| (i < grid.GetUpperBound(0) - 4 && j < grid.GetUpperBound(1) - 4 && grid[i + 1, j + 1] == dotColor && grid[i + 2, j + 2] == dotColor && grid[i + 3, j + 3] == dotColor && grid[i + 4, j + 4] == dotColor)){ShowWin(dotColor);}if((i > 3 && j < grid.GetUpperBound(1) - 4 && grid[i - 1, j + 1] == dotColor && grid[i - 2, j + 2] == dotColor && grid[i - 3, j + 3] == dotColor && grid[i - 4, j + 4] == dotColor)|| (i > 2 && i < grid.GetUpperBound(0) - 1 && j > 0 && j <grid.GetUpperBound(1) - 3 && grid[i - 1, j + 1] == dotColor && grid[i - 2, j + 2] == dotColor && grid[i - 3, j + 3] == dotColor && grid[i + 1, j - 1] == dotColor)|| (i > 1 && i < grid.GetUpperBound(0) - 2 && j > 1 && j <grid.GetUpperBound(1) - 2 && grid[i - 1, j - 1] == dotColor && grid[i - 2, j - 2] == dotColor && grid[i + 1, j + 1] == dotColor && grid[i + 2, j + 2] == dotColor)|| (i > 0 && i < grid.GetUpperBound(0) - 3 && j > 2 && j <grid.GetUpperBound(1) - 1 && grid[i - 1, j + 1] == dotColor && grid[i + 1, j - 1] == dotColor && grid[i + 2, j - 2] == dotColor && grid[i + 3, j - 3] == dotColor)|| (i < grid.GetUpperBound(0) - 4 && j > 3 && grid[i + 1, j - 1] == dotColor && grid[i + 2, j - 2] == dotColor && grid[i + 3, j - 3] == dotColor && grid[i + 4, j - 4] == dotColor)){ShowWin(dotColor);}}}private void ShowWin(int dotColor){timer.Enabled = false;gamePlayer[0].started = false;gamePlayer[1].started = false;this.ResetGrid();service.SendToBoth(this, string.Format("Win,{0},{1},{2}",dotColor, gamePlayer[0].grade, gamePlayer[1].grade));}public void UnsetDot(int i, int j, int color){if (color == NextPlayer){SetDot(i, j, color);NextPlayer = (NextPlayer + 1) % 2;}}}Player:struct Player{public User user;public bool started;public int grade;public bool someone;}Service:class Service{private ListBox listbox;private delegate void AddItemDelegate(string str);private AddItemDelegate addItemDelegate;public Service(ListBox listbox){this.listbox = listbox;addItemDelegate = new AddItemDelegate(AddItem);}public void AddItem(string str){if (listbox.InvokeRequired){listbox.Invoke(addItemDelegate, str);}else{listbox.Items.Add(str);listbox.SelectedIndex = listbox.Items.Count - 1; listbox.ClearSelected();}}public void SendToOne(User user, string str){try{user.sw.WriteLine(str);user.sw.Flush();AddItem(string.Format("向{0}发送{1}", erName, str));}catch{AddItem(string.Format("向{0}发送信息失败", erName));}}public void SendToBoth(GameTable gameTable, string str){for (int i = 0; i < 2; i++){if (gameTable.gamePlayer[i].someone == true){SendToOne(gameTable.gamePlayer[i].user, str);}}}public void SendToAll(System.Collections.Generic.List<User> userList, string str) {for (int i = 0; i < userList.Count; i++){SendToOne(userList[i], str);}}}User:class User{public TcpClient client { get; private set; }public StreamReader sr { get; private set; }public StreamWriter sw { get; private set; }public string userName { get; set; }public User(TcpClient client){this.client = client;erName = "";NetworkStream netStream = client.GetStream();sr = new StreamReader(netStream, System.Text.Encoding.UTF8);sw = new StreamWriter(netStream, System.Text.Encoding.UTF8);}}Form1:public partial class Form1 : Form{private int maxUsers = 100;System.Collections.Generic.List<User> userList = new List<User>();private int maxTables = 50;private GameTable[] gameTable;IPAddress localAddress;private int port = 51888;private TcpListener myListener;private Service service;public Form1(){InitializeComponent();service = new Service(listBox1);}private void btn1_Click(object sender, EventArgs e){listBox1.Items.Clear();gameTable = new GameTable[maxTables];for (int i = 0; i < maxTables; i++){gameTable[i] = new GameTable(listBox1);}myListener = new TcpListener(localAddress, port);myListener.Start();service.AddItem(string.Format("开始在{0}:{1}监听客户连接", localAddress, port));ThreadStart ts = new ThreadStart(ListenClientConnect);Thread myThread = new Thread(ts);myThread.Start();btn1.Enabled = false;btn2.Enabled = true;}private void btn2_Click(object sender, EventArgs e){for (int i = 0; i < maxTables; i++){gameTable[i].StopTimer();}service.AddItem(string.Format("目前连接用户数:{0}", userList.Count)); service.AddItem("开始停止服务,并依次使用户退出!");for (int i = 0; i < userList.Count; i++){userList[i].client.Close();}myListener.Stop();btn1.Enabled = true;btn2.Enabled = false;}private void Form1_Load(object sender, EventArgs e){listBox1.HorizontalScrollbar = true;IPAddress[] addrIP = Dns.GetHostAddresses(Dns.GetHostName());localAddress = addrIP[0];btn2.Enabled = false;}private void ListenClientConnect(){while (true){TcpClient newClient = null;try{newClient = myListener.AcceptTcpClient();}catch{break;}ParameterizedThreadStart pts = new ParameterizedThreadStart(ReceiveData);Thread threadReceive = new Thread(pts);User user = new User(newClient);threadReceive.Start(user);userList.Add(user);service.AddItem(string.Format("{0}进入",newClient.Client.RemoteEndPoint));service.AddItem(string.Format("当前连接用户数:{0}", userList.Count)); }}private void ReceiveData(object obj){User user = (User)obj;TcpClient client = user.client;bool normalExit = false;bool exitWhile = false;while (exitWhile == false){string receiveString = null;try{receiveString = user.sr.ReadLine();}catch{service.AddItem("接收数据失败");}if (receiveString == null){if (normalExit == false){if (client.Connected == true){service.AddItem(string.Format("与{0}失去联系,已终止接收该用户信息",client.Client.RemoteEndPoint));}RemoveClientfromPlayer(user);}break;}service.AddItem(string.Format("来自{0}:{1}", erName, receiveString));string[] splitString = receiveString.Split(',');int tableIndex = -1;int side = -1;int anotherSide = -1;string sendString = "";string command = splitString[0].ToLower();switch (command){case"login":if (userList.Count > maxUsers){sendString = "Sorry";service.SendToOne(user, sendString);service.AddItem("人数已满,拒绝" +splitString[1] + "进入游戏室");exitWhile = true;}else{erName = string.Format("[{0}--{1}]", splitString[1], client.Client.RemoteEndPoint);sendString = "Tables," + this.GetOnlineString();service.SendToOne(user, sendString);}break;case"logout":service.AddItem(string.Format("{0}退出游戏室", erName)); normalExit = true;exitWhile = true;break;case"sitdown":tableIndex = int.Parse(splitString[1]);side = int.Parse(splitString[2]);gameTable[tableIndex].gamePlayer[side].user = user;gameTable[tableIndex].gamePlayer[side].someone = true;service.AddItem(string.Format("{0}在第{1}桌第{2}座入座",erName, tableIndex + 1, side + 1));anotherSide = (side + 1) % 2;if (gameTable[tableIndex].gamePlayer[anotherSide].someone == true){sendString = string.Format("SitDown,{0},{1}", anotherSide,gameTable[tableIndex].gamePlayer[anotherSide]erName);service.SendToOne(user, sendString);}sendString = string.Format("SitDown,{0},{1}", side,erName);service.SendToBoth(gameTable[tableIndex], sendString);service.SendToAll(userList, "Tables," + this.GetOnlineString());break;case"getup":tableIndex = int.Parse(splitString[1]);side = int.Parse(splitString[2]);service.AddItem(string.Format("{0}离座,返回游戏室", erName));gameTable[tableIndex].StopTimer();service.SendToBoth(gameTable[tableIndex],string.Format("GetUp,{0},{1}", side, erName));gameTable[tableIndex].gamePlayer[side].someone = false;gameTable[tableIndex].gamePlayer[side].started = false;gameTable[tableIndex].gamePlayer[side].grade = 0;anotherSide = (side + 1) % 2;if (gameTable[tableIndex].gamePlayer[anotherSide].someone ==true){gameTable[tableIndex].gamePlayer[anotherSide].started = false;gameTable[tableIndex].gamePlayer[anotherSide].grade = 0;}service.SendToAll(userList, "Tables," + this.GetOnlineString());break;case"level":tableIndex = int.Parse(splitString[1]);gameTable[tableIndex].SetTimerLevel(int.Parse(splitString[2])); service.SendToBoth(gameTable[tableIndex], receiveString);break;case"talk":tableIndex = int.Parse(splitString[1]);sendString = string.Format("Talk,{0},{1}", erName,receiveString.Substring(splitString[0].Length +splitString[1].Length));service.SendToBoth(gameTable[tableIndex], sendString);break;case"start":tableIndex = int.Parse(splitString[1]);side = int.Parse(splitString[2]);gameTable[tableIndex].gamePlayer[side].started = true;if (side == 0){anotherSide = 1;sendString = "Message,黑方已开始。