五子棋实习报告Word格式.docx
- 文档编号:18160902
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:19
- 大小:326.08KB
五子棋实习报告Word格式.docx
《五子棋实习报告Word格式.docx》由会员分享,可在线阅读,更多相关《五子棋实习报告Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
//桌号及座位号,格式是:
桌号:
座位号
intscore;
//分数
SocketSocket=null;
//套接字
ObjectOutputStreamoutput=null;
//输出流
ObjectInputStreaminput=null;
//输入流
Nodenext=null;
//保存链表中下一节点的指针
}
2、下面是服务器通过链表记录的客户对像流来转发数据给相应的客户端。
代码还是简单明了的。
如:
if(type2.equalsIgnoreCase("
重新开局"
))
{
StringisResart=(String)node.input.readObject();
tobody.output.writeObject("
下棋操作"
);
tobody.output.flush();
tobody.output.writeObject(isResart);
//System.out.println("
isResart:
"
+isResart);
}
3、由于这是一个可以有十六个玩家进来的游戏,那么怎样确定哪个玩家与哪个玩家在同一张桌子上下棋呢?
我这里用到的链表记录的StringtableNum=null;
座位号。
如第一张桌第一个坐位与第二个坐位的记录是:
0:
0;
1。
以此类推。
1:
0,1:
1;
2:
0,2:
1……
服务器的根据桌号与坐位号来转发数据的。
用IF语句判断。
获得对手的对像流来发送数据。
//获取发送对象
Stringtable=node.tableNum.substring(0,node.tableNum.indexOf("
:
));
Stringseat=node.tableNum.substring(node.tableNum.indexOf("
)+1);
StringtableNum=null;
if(Integer.parseInt(seat)==0)
tableNum=table+"
+1;
else
+0;
tobody=userInfoList.findtable(tableNum);
客户端
1、棋盘里的棋子是用一个整型二维数组来记录的。
GramP[x][y],x代表横的格数,并是具体坐标;
y代表竖的格数,并是具体坐标;
x*28、y*28就是具体坐标。
0代表没有棋子,1代表白棋,2代表黑棋。
2、判断输赢的方法很简单,每下一个棋子,都要判断一次。
在当前棋子的0、45、90、135度方向上判断是否有五个同样的棋子相连。
这里用到了y=kx+b函数来计算。
要分开黑棋与白棋的判断,定义一个入口参数,增加代码的复用性,输与赢会用到重画方法,所以也定义了Graphicsg入口参数。
代码如下:
publicvoidisWin(intchessID,Graphicsg)
{
//横向判断
for(intk=0;
k<
19;
k++)
{
if(GramP[k][y]==chessID)
{
++whiteScore;
}else
whiteScore=0;
}
//如果大于五子连珠,就为赢
if(whiteScore>
=5)
win_tip(chessID,g);
break;
}
whiteScore=0;
//竖向判断
for(inth=0;
h<
h++)
if(GramP[x][h]==chessID)
//135向判断
intb1;
b1=y-x;
if(b1>
=0)
for(inta=0,b=b1;
b<
a++,b++)
if(GramP[a][b]==chessID)
{
++whiteScore;
}else
whiteScore=0;
}
if(whiteScore>
win_tip(chessID,g);
break;
whiteScore=0;
}else
for(inta=-b1,b=0;
a<
//45向判断
intb2;
b2=x+y;
if(b2<
=18)
for(intc=b2,d=0;
c>
=0;
c--,d++)
if(GramP[c][d]==chessID)
for(intc=18,d=b2-18;
d<
//平局
intcount=0;
for(inti=0;
i<
i++)
for(intj=0;
j<
j++)
if(GramP[i][j]==chessID)
count++;
if(count==180)
win_tip(3,g);
}
3、悔棋分为悔一步还是悔两步。
由一个布尔变量来判断,如果下完棋再悔棋,只悔一个棋。
如果没下棋,就悔两个棋。
由一维的字符串数组ReGame[]来记录下棋的先后顺序。
格式中:
ReGame[R++]=x+"
+y;
下面是悔两个棋子的代码。
publicvoidregretGrame2()
361;
if(ReGame[i]==null)
//System.out.println(ReGame[i-1]);
//System.out.println(ReGame[i-2]);
StringX1=ReGame[i-1].substring(0,ReGame[i-1].indexOf("
StringY1=ReGame[i-1].substring(ReGame[i-1].indexOf("
StringX2=ReGame[i-2].substring(0,ReGame[i-2].indexOf("
StringY2=ReGame[i-2].substring(ReGame[i-2].indexOf("
GramP[Integer.parseInt(X1)][Integer.parseInt(Y1)]=0;
GramP[Integer.parseInt(X2)][Integer.parseInt(Y2)]=0;
ReGame[i-1]=null;
ReGame[i-2]=null;
R-=2;
repaint();
悔一个棋子的,类似。
这只是悔棋函数,只能应用于本用户进行悔棋操,与电脑下棋的悔棋,就直接调用这个函数即可。
但是在联网模式中,通过对像流向服务器发送悔棋标识,再由服务器转发给对手,如果对手同意的吧,对手就会调用悔棋函数,进行自身棋盘的悔棋,同时会向服务器返回一个yes1或yes2标识,发起方收到了,也会调用悔棋函数进行悔棋操作。
如果对方不同意,则会返回一个no标识,发起方只会提示玩家,而不进行悔棋操作。
认输及和棋的步骤类似,不再累述。
下面是悔棋操作的部分主要代码:
发起请求悔棋:
//请求悔棋
publicvoidisRegretGrame()
if(R>
=2&
&
!
isEnd)//只有两个棋子以上才可以悔棋,否则数组会越界.分胜负时也不能悔棋
if(flag)//下棋前,悔棋
try{
oos.writeObject("
oos.flush();
悔棋"
isRegret2"
}catch(IOExceptione){
e.printStackTrace();
}else//下棋后,悔棋
isRegret1"
JOptionPane.showMessageDialog(this,"
不能执行悔棋操作"
"
警告"
JOptionPane.WARNING_MESSAGE);
服务器转发悔棋请求:
这只是服务转发的悔棋部分的数据。
Stringtype=(String)node.input.readObject();
//读取信息类型
if(type.equalsIgnoreCase("
{
StringisRegret=(String)node.input.readObject();
tobody.output.writeObject(isRegret);
收接悔棋请求:
下面代码是在客户端收接数据的线程里的。
Stringtype=(String)ois.readObject();
if(type.equalsIgnoreCase("
StringisRegret=(String)ois.readObject();
if("
yes2"
.equalsIgnoreCase(isRegret))
{
regretGrame2();
}
elseif("
yes1"
regretGrame1();
}elseif("
no1"
.equalsIgnoreCase(isRegret)||"
no2"
JOptionPane.showMessageDialog(this,"
对方不同意悔棋"
提示"
JOptionPane.WARNING_MESSAGE);
intresult=JOptionPane.showConfirmDialog(this,"
对方请求悔棋,是否同意?
JOptionPane.YES_NO_OPTION,JOptionPane.INFORMATION_MESSAGE);
if(result==JOptionPane.YES_OPTION)
oos.writeObject("
oos.flush();
}elseif(result==JOptionPane.NO_OPTION)
//System.out.println("
oos.writeObject("
聊天模块
1、文字聊天,也是通过服务器转发数据的,客户端就接收与显示。
在这里不再详说了。
2、重点是语音聊天,这里的语音连接,首先通过服务器转发发起方的语音标识,对方收到后,如果选择“是”,那它就会通过服务器转发IP地址给发起方,并同时起动serversocket监听。
发起方收到对方同意语音连接的标识与IP地址后,就可以与对方连接了,语音链路就建起了。
断开的思路也是差不多的。
练习模式
1、电脑下棋的算法:
通过遍历棋盘,计算权值,哪个位置的权值最高,就在哪个位置下棋。
权值的大小预定为:
//黑白白空50
//空白白空100
//黑白白白空500
//空白白白空1000
//黑白白白白空5000
//空白白白白空10000
//白白白白白100000
首先假定下棋点,再计算权值之和的大小。
权值之和=0度方向的带胜权值和堵敌的权值之和+45度方向的带胜权值和堵敌的权值之和+90度方向的带胜权值和堵敌的权值之和+135度方向的带胜权值和堵敌的权值之和.
下面代码,假定落子点,再把四个方向上的的权值加起来。
//记录当前假定的落子点
privateintgetQuan(inti,intj)
intq=0;
//求当前位置的权值
q+=getQuan0(i,j);
//得到水平方向上的权值,下面类似
q+=getQuan90(i,j);
q+=getQuan135(i,j);
q+=getQuan45(i,j);
returnq;
下面是只是求水平权值的代码,通过一个二维二元数组来左右求索棋子的个数。
//水平权值
privateintgetQuan0(inti,intj){
intsamechessNumS=0;
//相同棋子的个数
intsamechessNumF=0;
intblankNumS=0;
//空子的个数
intblankNumF=0;
intq=0,qS=0,qF=0;
int[][]ij0=newint[2][2];
//计算权值用的
ij0[0][0]=ij0[0][1]=i;
ij0[1][0]=ij0[1][1]=j;
samechessNumS=getsamechessNum0(ij0,back);
//得到黑子数目
if(ij0[0][0]>
if(curchess[ij0[0][0]][ij0[1][0]]==Chess)
blankNumS++;
if(ij0[0][1]<
19)
if(curchess[ij0[0][1]][ij0[1][1]]==Chess)
qS=getQuanpart(samechessNumS,blankNumS);
//得到速胜权值
samechessNumF=getsamechessNum0(ij0,white);
//得到白子数目
blankNumF++;
qF=getQuanpart(samechessNumF,blankNumF);
//得到堵敌权值
q=qS+qF;
//得到水平方向的同子数目
privateintgetsamechessNum0(int[][]qij,intchessID){
intnum=1;
//存储相同棋子数目,当前点满足条件
qij[0][0]--;
//向左探索我们只探索临近的4个点,注意不要出边界
while(qij[0][0]>
=0&
num<
5)
if(curchess[qij[0][0]][qij[1][0]]!
=chessID)break;
num++;
qij[0][0]--;
qij[0][1]++;
//向右求索
while(qij[0][1]<
19&
if(curchess[qij[0][1]][qij[1][1]]!
qij[0][1]++;
returnnum;
//求得某一方向上的一半权值
privateintgetQuanpart(intsame
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 五子棋 实习 报告