一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - AI算法實現五子棋(java)

AI算法實現五子棋(java)

2021-06-02 13:46胡豫南 Java教程

這篇文章主要為大家詳細介紹了AI算法實現五子棋,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了ai算法實現五子棋的具體代碼,供大家參考,具體內容如下

首先,實現一個五子棋要有一個棋盤,然后在這個棋盤上我們再來畫出圖畫,五子棋棋盤有固定的行數和列數,再加上界面的大小和菜單欄,這些數據可能很多個類都需要用到,我們可以先考慮自己寫一個接口用來存儲這些數據:

AI算法實現五子棋(java)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface config {
 public static final int size=703;
 //面板大小
 public static final int x0=size/19*2-8;
 public static final int y0=x0-15;
 //棋盤網格起始點
 public static final int wid=size/19;
 //行寬
 public static final int line=15;
 //行數
 public static final int chess=wid;
 //五子棋棋子大小
 
}

這個時候我們來考慮寫一個五子棋界面,除了常用的界面寫法之外,考慮到五子棋的悔棋和重新開始,我們需要重寫paint方法,在需要的時候調用來達到更新棋盤的作用。

?
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
import java.awt.basicstroke;
import java.awt.borderlayout;
import java.awt.color;
import java.awt.dimension;
import java.awt.graphics;
import java.awt.graphics2d;
 
import javax.swing.jpanel;
 
 
public class fivebord extends jpanel implements config{
 private static final long serialversionuid = 1l;
 private int point[][]=new int [size][size];
 
 public static void main(string[] args) {
 fivebord fb = new fivebord();
 fb.showfivebord();
 }
 
 public void showfivebord() {
 //一下是關于界面的常規設置
 javax.swing.jframe jf = new javax.swing.jframe();
 jf.settitle("fivebord");
 jf.setsize(size+100, size);
 jf.setdefaultcloseoperation(3);
 jf.setlocationrelativeto(null);
 jf.setlayout(new borderlayout());
 
 jpanel jp1=new jpanel();
 jp1.setbackground(color.orange);
 jp1.setpreferredsize(new dimension(100, size));
 jf.add(jp1,borderlayout.east);
 
 javax.swing.jbutton jbu1 = new javax.swing.jbutton("悔棋");
 jp1.add(jbu1);
 
 javax.swing.jbutton jbu2 = new javax.swing.jbutton("人機");
 jp1.add(jbu2);
 
 javax.swing.jbutton jbu3 = new javax.swing.jbutton("人人");
 jp1.add(jbu3);
 
 this.setbackground(color.yellow);
 jf.add(this,borderlayout.center);
 
 jf.setvisible(true);
 
 //以下給界面添加監聽器,包括畫板和按鈕
  drawmouse mouse=new drawmouse(this);
  jbu1.addactionlistener(mouse);
  jbu2.addactionlistener(mouse);
  jbu3.addactionlistener(mouse);
  this.addmouselistener(mouse);
  //監聽器中需要考慮當前棋盤上的棋子和位置
  mouse.setpoint(point);
    
 
 }
 public void paint(graphics g) {
 super.paint(g);
 //super.paint
 //由于paint函數是界面自帶的函數且在某些時候會自動調用
 //super.paint(g)表示屏蔽父類的函數內容,換做自己接下來改寫的內容
 graphics2d gr = (graphics2d)g;
 gr.setstroke(new basicstroke(1));
 //2d畫筆變粗度為1
 for(int i=x0;i<=x0+line*wid;i+=wid){
 for(int j=y0;j<=y0+line*wid;j+=wid){
 g.drawline(x0, j, x0+line*wid, j);
 g.drawline(i, y0, i,y0+line*wid);
 }
 }
 //畫內部16格
 gr.setstroke(new basicstroke(2));
 //畫筆粗度變為2
 g.drawline(x0-wid, y0-wid, x0-wid, y0+(line+1)*wid);
 g.drawline(x0-wid, y0-wid, x0+(line+1)*wid, y0-wid);
 g.drawline(x0+(line+1)*wid, y0-wid, x0+(line+1)*wid, y0+(line+1)*wid);
 g.drawline(x0-wid, y0+(line+1)*wid, x0+(line+1)*wid, y0+(line+1)*wid);
 //畫四周較粗的邊框(美觀起見,沒有實際意義)
 for(int i=x0;i<=x0+(wid*(line+1));i+=wid){
   for(int j=y0;j<=y0+(line+1)*wid;j+=wid){
   if(point[i][j]==1){
   //畫黑棋
   g.setcolor(color.black);
   g.filloval(i-wid/2, j-wid/2, wid, wid);
   }
   else if(point[i][j]==2){
   //畫白棋
   g.setcolor(color.white);
   g.filloval(i-wid/2, j-wid/2, wid, wid);
   }
   }
  }
 //根據point的內容畫出相應的點(即棋子)
 }
 
}

最最重要的就是監聽器部分了,除了具有相應的監聽功能,還要在每次人下棋之后智能判斷出機器所需要下的位置,于此同時,每下一個棋子,都要判斷是否已經有五子連成線進而提示輸贏。

?
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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
import java.awt.color;
import java.awt.graphics;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.awt.event.mouseadapter;
import java.awt.event.mouseevent;
import java.util.hashmap;
 
import javax.swing.joptionpane;
 
public class drawmouse extends mouseadapter implements config,actionlistener{
 //添加動作監聽器(監聽按鈕)和鼠標監聽器(鼠標所點位置畫棋子)
 private graphics g;
 private int x,y,co=1,index=0;
 private int point[][];
 private int pointweight[][]=new int [x0+(line+1)*wid][y0+(line+1)*wid];
 private int orderx[]=new int [x0+(line+1)*wid],ordery[]=new int [y0+(line+1)*wid];
 private fivebord fb;
 private int pc=0;
 public hashmap <string,integer> hm = new hashmap <string,integer>();
 //哈希表用來存放不同棋子布局下的不同權值
 
 
 drawmouse(fivebord fb) {
 this.g = fb.getgraphics();
 this.fb=fb;
 sethashmap();
 }
 //傳棋子數組
 public void setpoint(int point[][]){
  this.point=point;
 }
 public void sethashmap(){
 hm.put("1", 1);
 //某一方向線上只有一個黑棋
 hm.put("12", 5);
 //某一方向線上緊接著一個黑棋有一個白棋
 hm.put("11", 10);
 hm.put("112", 15);
 //某一方向線上緊接著兩個相鄰的黑棋后有一個白棋(以此類推)
 hm.put("111", 100);
 hm.put("1112", 105);
 hm.put("1111", 1000);
 
 hm.put("2", 1);
 hm.put("21", 5);
 hm.put("22", 10);
 hm.put("221", 15);
 hm.put("222", 100);
 hm.put("2221", 105);
 hm.put("2222", 1000);
 }
 
 public void actionperformed(actionevent e){
 //悔棋操作,將棋子數目減一,然后重繪界面即可
 if("悔棋".equals(e.getactioncommand())&&index>0){
 system.out.println("悔棋");
 index--;
 point[orderx[index]][ordery[index]]=0;
 fb.paint(g);
 }
 //人機模式一旦點擊,界面所有棋子清零,開始人機對戰(pc=1)
 if("人機".equals(e.getactioncommand())){
 system.out.println("人機");
  pc=1;
  index=0;
  for(int i=x0;i<=x0+wid*line;i+=wid){
  for(int j=y0;j<=y0+wid*line;j+=wid){
  point[i][j]=0;
  }
  }
  fb.paint(g);
 }
 //人人對戰,也是點擊按鈕棋子清零,開始人人對戰(pc=0)
 if("人人".equals(e.getactioncommand())){
 system.out.println("人機");
  pc=0;
  index=0;
  for(int i=x0;i<=x0+wid*line;i+=wid){
  for(int j=y0;j<=y0+wid*line;j+=wid){
  point[i][j]=0;
  }
  }
  fb.paint(g);
 }
 }
 
 public void mouseclicked(mouseevent e) {
 x=e.getx();
 y=e.gety();
 //得到點擊的點
 if((x-x0)%wid>=wid/2){
 x=x-(x-x0)%wid+wid;
 }
 else{
 x=x-(x-x0)%wid;
 }
 if((y-y0)%wid>=wid/2){
 y=y-(y-y0)%wid+wid;
 }
 else{
 y=y-(y-y0)%wid;
 }
 //對點的位置進行修正(保證每次點擊都正好下在網格交匯處)
 if(point[x][y]==0&&x>=x0&&x<=x0+wid*line&&y>=y0&&y<=y0+wid*line){
 //人人對戰:直接用鼠標檢測,依次變換顏色黑或白
 if(pc==0){
 if(g.getcolor()==color.black){
  g.setcolor(color.white);
  co=2;
 }
 else{
  g.setcolor(color.black);
  co=1;
 }
 }
 //人機對戰,每次人下過棋子之后,計算機根據現有棋盤布局對棋局分析和總和并判斷機器需要下的位置
 else if(pc==1){
 g.setcolor(color.black);
 co=1;
 }
 g.filloval(x-wid/2, y-wid/2, wid, wid);
  point[x][y]=co;
  system.out.println(index+ " "+ x+" "+y);
  orderx[index]=x;
  ordery[index]=y;
  index++;
  if(exam()==0){
  //自己敲代碼過程中的驗證、、、、、、可以不用在意這類輸出。
  system.out.println("hahahahhhaahhahah");
  if(pc==1){
  system.out.println("hehehehehehehehehehehe");
  g.setcolor(color.white);
  co=2;
  ai();
  exam();
  }
  }
 }
 
 }
 //檢測是否有一方獲勝,跳出提示框提示某一方獲勝
 public int exam(){
 int w=0;
 for(int i=x0-wid;i<=x0+wid*(line+1);i+=wid){
 for(int j=y0-wid;j<=y0+wid*(line+1);j+=wid){
 if(point[i][j]!=0){
  int exam1=0,exam2=0,exam3=0,exam4=0;
  //水平、豎直、左斜、右斜四個方向上同色棋子相連最多的個數
  for(int t=wid;t<5*wid;t+=wid){
  if(i+t<=x0+wid*(line+1)&&point[i+t][j]==point[i][j]){
  exam1++;
  }
  if(j+t<=y0+wid*(line+1)&&point[i][j+t]==point[i][j]){
  exam2++;
  }
  if(i+t<=x0+wid*(line+1)&&j+t<=y0+wid*(line+1)&&point[i+t][j+t]==point[i][j]){
  exam3++;
  }
  if(i+t<=x0+wid*(line+1)&&j>=t&&point[i+t][j-t]==point[i][j]){
  exam4++;
  }
  }
  system.out.println(exam1+" "+exam2+" " +exam3+" "+exam4);
  if(exam1==4||exam2==4||exam3==4||exam4==4){//某一方向上同色5子相連,一方獲勝
  if(point[i][j]==1){
  w=1;
  //彈出提示框
  joptionpane.showmessagedialog(null, "黑子勝");
  }
  else{
  w=2;
  joptionpane.showmessagedialog(null, "白子勝"); 
  }
  i=x0+wid*(line+1)+1;
  break;
  }
 }
 }
 }
 return w;
 }
 //ai算法
 //分別向左、香油、左下、、、、、等8個方向檢測棋子布局情況并累加在該點的權值上
 //再找出圖片上沒有棋子并且權值最大的點下棋子
 //記得每次下棋將各個空位置的權值歸0,以便下一次計算權值累加
 public void ai(){
 for(int i=x0;i<x0+wid*(line+1);i+=wid){
  for(int j=y0;j<y0+wid*(line+1);j+=wid){
 if(point[i][j]==0){
  //像右尋找
  //system.out.print("pointweight["+(i-x0)/wid+"]["+(j-y0)/wid+"]:");
  int color=0;
  string code="";
  for(int k=i+wid;k<=x0+wid*line;k+=wid){
  if(point[k][j]!=0){
  if(color==0){
  color=point[k][j];
  code+=point[k][j];
  }
  else{
  if(point[k][j]==color){
   code+=point[k][j];
  }
  else{
   code+=point[k][j];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  integer value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
  //向下尋找
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=j+wid;k<=x0+wid*line;k+=wid){
  if(point[i][k]!=0){
  if(color==0){
  color=point[i][k];
  code+=point[i][k];
  }
  else{
  if(point[i][k]==color){
   code+=point[i][k];
  }
  else{
   code+=point[i][k];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
  //向左
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=i-wid;k>=x0;k-=wid){
  if(point[k][j]!=0){
  if(color==0){
  color=point[k][j];
  code+=point[k][j];
  }
  else{
  if(point[k][j]==color){
   code+=point[k][j];
  }
  else{
   code+=point[k][j];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
  //向上
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=j-wid;k>=y0;k-=wid){
  if(point[i][k]!=0){
  if(color==0){
  color=point[i][k];
  code+=point[i][k];
  }
  else{
  if(point[i][k]==color){
   code+=point[i][k];
  }
  else{
   code+=point[i][k];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
  //向右上尋找
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=i+wid,w=j+wid;k<=x0+wid*line&&w<=y0+wid*line;k+=wid,w+=wid){
  if(point[k][w]!=0){
  if(color==0){
  color=point[k][w];
  code+=point[k][w];
  }
  else{
  if(point[k][w]==color){
   code+=point[k][w];
  }
  else{
   code+=point[k][w];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=i-wid,w=j-wid;k>=x0&&w>=y0;k-=wid,w-=wid){
  if(point[k][w]!=0){
  if(color==0){
  color=point[k][w];
  code+=point[k][w];
  }
  else{
  if(point[k][w]==color){
   code+=point[k][w];
  }
  else{
   code+=point[k][w];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=i+wid,w=j-wid;k<=x0+line*wid&&w>=y0;k+=wid,w-=wid){
  if(point[k][w]!=0){
  if(color==0){
  color=point[k][w];
  code+=point[k][w];
  }
  else{
  if(point[k][w]==color){
   code+=point[k][w];
  }
  else{
   code+=point[k][w];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
//  system.out.print(pointweight[i][j]+" ");
  code="";
  color=0;
  for(int k=i-wid,w=j+wid;k>=x0&&w<=y0+line*wid;k-=wid,w+=wid){
  if(point[k][w]!=0){
  if(color==0){
  color=point[k][w];
  code+=point[k][w];
  }
  else{
  if(point[k][w]==color){
   code+=point[k][w];
  }
  else{
   code+=point[k][w];
   break;
  }
  }
  }
  else{
  break;
  }
  }
  value=hm.get(code);
  if(value != null){
  pointweight[i][j] += value;
  }
//  system.out.println(pointweight[i][j]);
 }
 }
 }
 //尋找最大權值的點并畫棋子
 int maxx=x0,maxy=y0;
  for(int i=x0;i<=x0+wid*line;i+=wid){
  for(int j=y0;j<=y0+wid*line;j+=wid){
  system.out.print(pointweight[i][j]+" ");
  if(pointweight[i][j]>pointweight[maxx][maxy]){
  maxx=i;
  maxy=j;
  }
  
  }
  system.out.println();
  }
  g.filloval(maxx-wid/2, maxy-wid/2, wid, wid);
  point[maxx][maxy]=co;
  system.out.println(index+ " "+ maxx+" "+maxy);
  orderx[index]=maxx;
  ordery[index]=maxy;
  index++;
  //全部權值歸零方便下次使用
  for(int i=x0;i<=x0+wid*line;i+=wid){
  for(int j=y0;j<=y0+wid*line;j+=wid){
  pointweight[i][j]=0;
  }
  }
 }
 
}

大概就是這個樣子了,權值那里設置的還是需要調整一下。運行結果截圖如下:

AI算法實現五子棋(java)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/weixin_42372777/article/details/81432083

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久99精品国产免费观看 | 亚洲AV久久久噜噜噜久久 | 精品亚洲视频在线观看 | 性关系视频免费网站在线观看 | 国产尤物视频 | 国产香蕉97碰碰久久人人 | 太紧太深了受不了黑人 | 日韩无砖专区2020在线 | 久久久免费观看 | a在线观看欧美在线观看 | 九九热在线视频观看这里只有精品 | 色琪琪原网站亚洲香蕉 | 免费稚嫩福利 | 亚洲娇小性hd | 成人精品在线 | 美女脱了内裤打开腿让人羞羞软件 | 国产伦码精品一区二区三区 | 亚洲精品福利一区二区在线观看 | 啪啪导航 | 免费观看日本 | 桃色导航 | 日韩国产欧美成人一区二区影院 | 久久久高清国产999尤物 | 三体动漫在线观看免费完整版2022 | 麻豆网站视频国产在线观看 | 91欧洲在线视精品在亚洲 | 国产a不卡片精品免费观看 国产aaa伦理片 | porno xxxx日本| 厨房里摸着乳丰满在线观看 | 日本漫画大全之工之口 | 国产在线一区二区视频 | 福利国产精品 | 交换余生在线播放免费 | 欧美日韩一区二区三区在线视频 | 激情自拍网 | www.99热| 视频一区在线免费观看 | 69japanese日本100| 搓光美女衣 | 免费高清在线视频色yeye | 国产区小视频 |