单机版五子棋

时间:2020-12-28 16:06:50

这两个星期学习了五子棋项目,写出了一个单机版的简单五子棋小游戏,由于这段时间都是被赶着写作业的节奏,也没太多时间,好吧,我承认我这也是在写作业单机版五子棋其中还有一些问题和功能无法和那些个高大上的版本相媲美,但还是让我对java的学习有了更好的理解。

长得不太好看,莫怪莫怪。。。

单机版五子棋

我大概说一下我的软件思路。

(一)把棋盘和界面都实现,主要用到了画图功能,这个不是重点,因为相比起下棋功能来,这些都算是小case了

(二)添加功能面板,考虑各种功能的实现,我是添加了好多的button,然后就给他们添加监听。如果我们软件设计的老师知道我这么干肯定会批死我的,这严重违背了他软件设计的原则,他再简单的软件都要考虑什么顶层架构,然后各种抽象啊,接口啊之类的,最后才能出现界面这种东西。有点乱,我想但也将就着用吧,功能的话,上面图片上都有。

(三)写功能实现代码。我就把悔棋,人机这两种功能分享一下吧,都做的不够完善,只是分享一下经验而已。人机的悔棋我还没有实现还原权值的功能,如果在人机模式下悔棋的话肯定最后数据会乱的,因为电脑是根据最大权值下棋。至于人机下棋,我只做了防守,没有做进攻,我想进攻应该也差不多,再用一个二维数组对电脑所下棋子的周围权值根据五子棋下棋规则做一定设置,再对防守的权值数组和进攻的权值数组进行判定,只要玩家不是活三或者冲四,电脑就可在进攻权值最大处下棋,否则就去堵玩家的棋,这大概是我的后续思路但还没实现,有兴趣朋友的可以去实现一下。

    

悔棋

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
       
       
      
      
/**
* 悔棋操作
*/
public void regret (){
//如果list表非空,可开始悔棋
if ( list . size ()> 0 ){
//保正悔的最后一颗棋仍能下所属颜 色的棋
//人人模式下悔棋
if (! compute ){
//获取当前所悔棋子的坐标
int xx =( int ) list . get ( list . size ()- 2 );
int yy =( int ) list . get ( list . size ()- 3 );
//移除list中最后三个元素,即一颗棋子的信息
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
chess . repaint ();
//在所悔棋子处,将棋盘值置零,使之能够继续下棋
chesses [ xx / 40 - 1 ][ yy / 40 - 1 ]= 0 ;
if ( flag == true ){
flag = false ;
}
else if ( flag == false ){
flag = true ;
}
}
//人机模式下悔棋
//悔棋时还要把所悔处周围的棋盘权值加上,这个还没时间实现
else {
//获取当前所悔棋子的坐标
int xx1 =( int ) list . get ( list . size ()- 2 );
int yy1 =( int ) list . get ( list . size ()- 3 );
int xx2 =( int ) list . get ( list . size ()- 5 );
int yy2 =( int ) list . get ( list . size ()- 6 );
//移除list中最后六个元素,即一颗白棋一颗黑棋的信息
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
list . remove ( list . size ()- 1 );
chess . repaint ();
//在所悔棋子处,将棋盘值置零,使之能够继续下棋
chesses [ xx1 / 40 - 1 ][ yy1 / 40 - 1 ]= 0 ;
chesses [ xx2 / 40 - 1 ][ yy2 / 40 - 1 ]= 0 ;
flag = true ;
}
}
else
JOptionPane . showMessageDialog ( this , "当前无棋子可悔啦!" );
}


人机

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
       
       
      
      
/**
* 电脑下棋策略
* 在权值最大处下棋
*/
public void auto_chess (){
//找出最大权值
int [] m = new int [ 100 ];
int [] n = new int [ 100 ];
int max = value [ 0 ][ 0 ];
int k = 0 ;
for ( int i = 0 ; i < 11 ; i ++)
for ( int j = 0 ; j < 11 ; j ++){
if ( value [ i ][ j ]> max ){
max = value [ i ][ j ];
m [ 0 ]= i ; n [ 0 ]= j ;
for ( int s = 1 ; s <= k ; s ++){
m [ s ]= 0 ; n [ s ]= 0 ;
}
k = 0 ;
}
if ( value [ i ][ j ]== max ){
max = value [ i ][ j ];
m [++ k ]= i ; n [ k ]= j ;
}
}
java . util . Random r = new java . util . Random ();
int x = r . nextInt ( k );
//System.out.println("k="+k+",x="+x);
//设置画笔颜色
if ( flag == true ){
//改变画布的颜色
g . setColor ( Color . black );
chesses [ m [ x ]][ n [ x ]] = 1 ; //黑色
flag = false ;
}
else if ( flag == false ){
//改变画布的颜色
g . setColor ( Color . white );
chesses [ m [ x ]][ n [ x ]] = 2 ; //白色
flag = true ;
}
//将下棋处的权值置为0
value [ m [ x ]][ n [ x ]]= 0 ;
print ();
//下棋
g . fillOval ( 40 *( n [ x ]+ 1 )- 15 , 40 *( m [ x ]+ 1 )- 15 , 30 , 30 );
//确保电脑下棋后人能下棋
flag_chess = false ;
list . add ( 40 *( n [ x ]+ 1 ));
list . add ( 40 *( m [ x ]+ 1 ));
list . add ( g . getColor ());
//电脑下棋后判断输赢
win ( m [ x ], n [ x ]);
}
/**
* 设置所下棋子周围八格的权值
* @param i 所下棋子横坐标
* @param j 所下棋子纵坐标
*/
public void set_value ( int i , int j , int per , int com ){
int t1 = 0 , t2 = 0 , t = 0 ;
//利用side[]的值判定棋子是活棋还是冲棋,s表示判定的棋子个数
//斜向棋子判定
//左上-----右下
for ( int s = 0 ; s < 4 ; s ++){
side [ s ]= 0 ;
} num = 0 ;
for ( int m = i , n = j ; m <= i + 4 && n <= j + 4 && m < 11 && n < 11 ; m ++, n ++){
if ( chesses [ m ][ n ]== per ){
num ++;
}
if ( chesses [ m ][ n ]== com ){
//if(flag1==false)
break ;
}
if ( chesses [ m ][ n ]== 0 ){
t = side [ num ]+ 1 ;
t1 = m ; t2 = n ;
//System.out.println("t1="+t1+",t2="+t2+",t="+t);
break ;
}
}
for ( int m = i , n = j ; m >= i - 4 && n >= j - 4 && m >= 0 && n >= 0 ; m --, n --){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){ num --;
//if(flag1==false)
if ( t == 1 ){ //System.out.println("see white!!");
if ( num == 4 ) value [ t1 ][ t2 ]+= 100 ;
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
if ( chesses [ m ][ n ]== 0 ){ num --;
if ( t == 1 ){
if ( num == 4 || num == 3 ){ value [ m ][ n ]+= 100 ; value [ t1 ][ t2 ]+= 100 ;}
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 ;
value [ m ][ n ]+= num *( num + 1 )* 5 ;
}
if ( t == 0 ){
if ( num == 4 ) value [ m ][ n ]+= 100 ;
value [ m ][ n ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
}
//}
//右上---左下
for ( int s = 0 ; s < 4 ; s ++){
side [ s ]= 0 ;
} num = 0 ; t1 = 0 ; t2 = 0 ; t = 0 ;
//if(i-4>=0&&j+4<11){
for ( int m = i , n = j ; m >= i - 4 && n <= j + 4 && m >= 0 && n < 11 ; m --, n ++){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){
//if(flag1==false)
break ;
}
if ( chesses [ m ][ n ]== 0 ){
t = side [ num ]+ 1 ;
t1 = m ; t2 = n ;
break ;
}
}
for ( int m = i , n = j ; m <= i + 4 && n >= j - 4 && m < 11 && n >= 0 ; m ++, n --){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){ num --;
if ( t == 1 ){
if ( num == 4 ) value [ t1 ][ t2 ]+= 100 ;
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
if ( chesses [ m ][ n ]== 0 ){ num --;
//此棋为活棋
if ( t == 1 ){
if ( num == 4 || num == 3 ){ value [ m ][ n ]+= 100 ; value [ t1 ][ t2 ]+= 100 ;}
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 ;
value [ m ][ n ]+= num *( num + 1 )* 5 ;
}
//此棋为冲棋
if ( t == 0 ){
if ( num == 4 ) value [ m ][ n ]+= 100 ;
value [ m ][ n ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
}
//}
//横向棋子判定
for ( int s = 0 ; s < 4 ; s ++){
side [ s ]= 0 ;
} num = 0 ; t1 = 0 ; t2 = 0 ; t = 0 ;
//if(j+4<11){
for ( int m = i , n = j ; n <= j + 4 && n < 11 ; n ++){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){
//if(flag1==false)
break ;
}
if ( chesses [ m ][ n ]== 0 ){
t = side [ num ]+ 1 ;
t1 = m ; t2 = n ;
break ;
}
}
for ( int m = i , n = j ; n >= 0 ; n --){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){ num --;
if ( t == 1 ){
if ( num == 4 ) value [ t1 ][ t2 ]+= 100 ;
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
if ( chesses [ m ][ n ]== 0 ){ num --;
if ( t == 1 ){
if ( num == 4 || num == 3 ){ value [ m ][ n ]+= 100 ; value [ t1 ][ t2 ]+= 100 ;}
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 ;
value [ m ][ n ]+= num *( num + 1 )* 5 ;
}
if ( t == 0 ){
if ( num == 4 ) value [ m ][ n ]+= 100 ;
value [ m ][ n ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
}
//}
//竖向棋子判定
for ( int s = 0 ; s < 4 ; s ++){
side [ s ]= 0 ;
} num = 0 ; t1 = 0 ; t2 = 0 ; t = 0 ;
//if(i+4<11){
for ( int m = i , n = j ; m <= i + 4 && m < 11 ; m ++){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){
//if(flag1==false)
break ;
}
if ( chesses [ m ][ n ]== 0 ){
t = side [ num ]+ 1 ;
t1 = m ; t2 = n ;
break ;
}
}
for ( int m = i , n = j ; m >= 0 ; m --){
if ( chesses [ m ][ n ]== per ){
num ++; //flag1=true;
}
if ( chesses [ m ][ n ]== com ){ num --;
if ( t == 1 ){
if ( num == 4 ) value [ t1 ][ t2 ]+= 100 ;
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
if ( chesses [ m ][ n ]== 0 ){ num --;
if ( t == 1 ){ System . out . println ( "num41=" + num );
if ( num == 4 || num == 3 ){ value [ m ][ n ]+= 100 ; value [ t1 ][ t2 ]+= 100 ;}
value [ t1 ][ t2 ]+= num *( num + 1 )* 5 ;
value [ m ][ n ]+= num *( num + 1 )* 5 ;
}
if ( t == 0 ){
if ( num == 4 ) value [ m ][ n ]+= 100 ;
value [ m ][ n ]+= num *( num + 1 )* 5 / 2 ;
}
break ;
}
}
}