好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

AI算法实现五子棋(java)

本文实例为大家分享了ai算法实现五子棋的具体代码,供大家参考,具体内容如下

首先,实现一个五子棋要有一个棋盘,然后在这个棋盘上我们再来画出图画,五子棋棋盘有固定的行数和列数,再加上界面的大小和菜单栏,这些数据可能很多个类都需要用到,我们可以先考虑自己写一个接口用来存储这些数据:

?

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 ;

   }

   }

  }

 

}

大概就是这个样子了,权值那里设置的还是需要调整一下。运行结果截图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

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

查看更多关于AI算法实现五子棋(java)的详细内容...

  阅读:11次