回 帖 发 新 帖 刷新版面

主题:关于五子棋

在五子棋里面,电脑下棋的算法该怎样写呀!
大家交流一下。

回复列表 (共9个回复)

沙发

应该类似于‘井字游戏’吧?
本人写过一个,但其中AI不高。
若有兴趣,请查阅代码。

板凳

我在http://www.hoker.58shop.com/bbs中写了一个
你们可以去看看
智商中下吧

3 楼

我以前也写过一个五子棋程序,但是我的硬盘已经完全格式化过N次,现在源程序找不到了.
当时我使用的算法也记不太清楚了,大概就是循环...再循环.
我的算法很简单,智商一般,抛砖引玉吧.
设棋盘的横\纵的点数为W\H,在循环以(4,4) TO (W-4,H-4)的每一点为中心(X,Y),再在内层循环中判断(X-4,Y-4) TO (X+4,Y+4)的范围内的局势,
首先每条线上要有足够的空位可以连成连续的5子,否则就不作下一步的计算.然后检查是否有成三\成四\双三\四交三等等,在线上的空位按优先度记入一个值,对弈双方的都要计算.
然后计算走哪一步棋可以正好占领对方优先度最高的位置,同时该位置最好是己方优先度较高的位置.当然,如果己方已能连成5子,就不必再理睬对方.
最后,就是在某些走棋的方案上进行优化.
源程序找不到了,当时作的笔记更找不到了,无法表述得清楚.更何况算法很垃圾,真表述清楚了反而让人见笑,呵呵.

4 楼

DECLARE SUB mouseTest ()
DECLARE SUB DrawMap (clor AS INTEGER)
DECLARE SUB Ball (x AS INTEGER, y AS INTEGER, i AS INTEGER)
DECLARE SUB ai (x AS INTEGER, y AS INTEGER, index AS INTEGER, ip AS INTEGER)
DECLARE SUB KillTest (x AS INTEGER, y AS INTEGER, ip AS INTEGER)
DECLARE SUB MouseSet (x AS INTEGER, y AS INTEGER, n AS INTEGER)
DECLARE SUB SETmouse (x AS INTEGER, y AS INTEGER)
DECLARE FUNCTION MouseX! ()
DECLARE FUNCTION MouseY! ()
DECLARE SUB MouseOn ()
DECLARE SUB MouseOff ()
DECLARE FUNCTION MouseClick% (flag AS INTEGER)
DECLARE FUNCTION MouseMove% ()
'$INCLUDE: 'qb.bi'
DIM SHARED REGS AS RegType



TYPE fangxiang
x AS INTEGER
y AS INTEGER
END TYPE
TYPE qizi
x AS INTEGER
y AS INTEGER
score AS LONG
END TYPE
DIM SHARED way(7) AS fangxiang
DIM SHARED q(15, 15) AS INTEGER
DIM SHARED mx AS INTEGER
DIM SHARED my AS INTEGER
DIM SHARED unit AS INTEGER
DIM value AS INTEGER
DIM x1 AS INTEGER
DIM y1 AS INTEGER
DIM x2 AS INTEGER
DIM y2 AS INTEGER
DIM i AS INTEGER
DIM SHARED fenshu(1 TO 4) AS INTEGER
fenshu(1) = 20000
fenshu(2) = 64
fenshu(3) = 8
fenshu(4) = 1


OPEN "setting.txt" FOR INPUT AS #1
FOR i = 1 TO 4
  INPUT #1, fenshu(i)
NEXT i
CLOSE #1

way(0).x = 1
way(1).x = 1
way(1).y = 1
way(2).y = 1
way(3).x = -1
way(3).y = 1
way(4).x = -1
way(5).x = -1
way(5).y = -1
way(6).y = -1
way(7).x = 1
way(7).y = -1
mx = 20
my = 20
unit = 26
DIM SHARED zi(65) AS qizi
DIM SHARED indexzi AS INTEGER
DIM i1 AS INTEGER
DIM i2 AS INTEGER
DIM score AS INTEGER
DIM SHARED kt AS INTEGER
DIM attack AS qizi
DIM defend AS qizi
DIM SHARED waiting AS INTEGER
DIM SHARED deep AS INTEGER
DIM SHARED clor AS INTEGER
deep = 3
SCREEN 12
DrawMap 2
MouseOn
mouseTest
Ball 8, 8, 1
DIM mx1 AS INTEGER, mx2 AS INTEGER, my1 AS INTEGER, my2 AS INTEGER
mx1 = 7: my1 = 7
LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
WHILE value = 0
t = TIMER
WHILE TIMER - t < .2 AND ink$ = ""
ink$ = INKEY$
WEND
SELECT CASE ink$
  CASE IS = " "
   x1 = mx1
   y1 = my1
   ink$ = ""
   GOTO 1
  CASE IS = CHR$(0) + CHR$(72)
   ink$ = ""
   IF my1 > 1 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    my1 = my1 - 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(80)
   ink$ = ""
   IF my1 < 15 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    my1 = my1 + 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(75)
   ink$ = ""
   IF mx1 > 1 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    mx1 = mx1 - 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(77)
   ink$ = ""
   IF mx1 < 15 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    mx1 = mx1 + 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
END SELECT

IF MouseClick(0) = 1 THEN
  x1 = (MouseX + unit / 2 - mx) \ unit + 1
  y1 = (MouseY + unit / 2 - my) \ unit + 1
1
  IF x1 > 0 AND x1 < 16 AND y1 > 0 AND y1 < 16 THEN
   IF q(x1, y1) = 0 THEN
    value = 1
    Ball x1, y1, 2
   END IF
  END IF
END IF
WEND
Ball 16 - y1, x1, 1

'Main Programme
x2 = 8
y2 = 8
ink$ = ""

WHILE ink$ <> CHR$(27)
  
t = TIMER
WHILE TIMER - t < .2 AND ink$ = ""
  ink$ = INKEY$
WEND

SELECT CASE ink$
  CASE IS = " "
   x1 = mx1
   y1 = my1
   ink$ = ""
   GOTO 2

  CASE IS = CHR$(0) + CHR$(72)
   ink$ = ""
   IF my1 > 1 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    my1 = my1 - 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(80)
   ink$ = ""
   IF my1 < 15 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    my1 = my1 + 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(75)
   ink$ = ""
   IF mx1 > 1 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    mx1 = mx1 - 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
  CASE IS = CHR$(0) + CHR$(77)
   ink$ = ""
   IF mx1 < 15 THEN
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), 8, B
    mx1 = mx1 + 1
    LINE (mx + (mx1 - 1) * unit - unit / 2 + 1, my + (my1 - 1) * unit - unit / 2 + 1)-STEP(unit - 2, unit - 2), clor, B
   END IF
END SELECT
IF MouseClick(0) = 1 THEN
  x1 = (MouseX + unit / 2 - mx) \ unit + 1
  y1 = (MouseY + unit / 2 - my) \ unit + 1
2
  IF x1 > 0 AND x1 < 16 AND y1 > 0 AND y1 < 16 THEN
   IF q(x1, y1) = 0 THEN
    MouseOff
    CIRCLE (mx + (x2 - 1) * unit, my + (y2 - 1) * unit), unit / 2 - 2, 0
    PAINT (mx + (x2 - 1) * unit, my + (y2 - 1) * unit), 0, 0
    MouseOn
    waiting = waiting + 1
    Ball x1, y1, 2
    KillTest x1, y1, 2
    IF kt = 1 THEN
     LOCATE 15, 30
     PRINT "You win!!"
     SLEEP
     END
    END IF
    IF q(attack.x, attack.y) > 0 THEN
     attack.score = -1
    ELSE
     indexzi = 0
     zi(0).score = 0
     q(attack.x, attack.y) = 1
     ai attack.x, attack.y, 2, 1
     attack.score = zi(0).score
     q(attack.x, attack.y) = 0
    END IF
    FOR i = 0 TO 65
     zi(i).score = 0
    NEXT i
    indexzi = 0
    ai x2, y2, 1, 1
    attack.score = attack.score / 1.1
    FOR i = 0 TO indexzi - 1
     IF zi(i).score > attack.score THEN
      SWAP attack.score, zi(i).score
      SWAP attack.x, zi(i).x
      SWAP attack.y, zi(i).y
     END IF
    NEXT i
    attack.score = attack.score * 1.1
    FOR i = 0 TO indexzi - 1
     zi(i).score = 0
    NEXT i
    indexzi = 0
    ai x1, y1, 1, 2
    i2 = indexzi - 1
   
    FOR i = 0 TO i2
     indexzi = i
     score = zi(i).score * .7
     zi(i).score = 0
     q(zi(i).x, zi(i).y) = 1
     ai zi(i).x, zi(i).y, 2, 1
     q(zi(i).x, zi(i).y) = 0
     zi(i).score = zi(i).score * .3 + score
    NEXT i
    indexzi = i

    IF q(defend.x, defend.y) > 0 THEN
     defend.score = -1
    END IF
   
    FOR i = 0 TO indexzi - 1
     IF zi(i).score > defend.score THEN
      SWAP defend.score, zi(i).score
      SWAP defend.x, zi(i).x
      SWAP defend.y, zi(i).y
     END IF
    NEXT i
   
    LOCATE 1, 20
    PRINT indexzi
    i1 = 0
    IF defend.score >= attack.score THEN
     zi(i1).x = defend.x
     zi(i1).y = defend.y
    ELSE
     zi(i1).x = attack.x
     zi(i1).y = attack.y
    END IF
    LOCATE 1, 1
    PRINT attack.x; " "; attack.y; ""; attack.score; "     ";
    PRINT defend.x; " "; defend.y; ""; defend.score; "       "


    Ball zi(i1).x, zi(i1).y, 1
    x2 = zi(i1).x
    y2 = zi(i1).y
    KillTest x2, y2, 1
    IF kt = 1 THEN
     LOCATE 15, 20
     PRINT "How foolish you are !!"
     SLEEP
     END
    END IF
   END IF
  END IF
END IF
IF waiting > 7 THEN
  deep = 4
END IF
MouseOff
CIRCLE (mx + (x2 - 1) * unit, my + (y2 - 1) * unit), unit / 2 - 2, 1
PAINT (mx + (x2 - 1) * unit, my + (y2 - 1) * unit), 1, 1
MouseOn
WEND

SUB ai (x AS INTEGER, y AS INTEGER, index AS INTEGER, ip AS INTEGER)
DIM i1 AS INTEGER
DIM i2 AS INTEGER
DIM x1 AS INTEGER
DIM y1 AS INTEGER
FOR i1 = 0 TO 7
  FOR i2 = 1 TO 4
   x1 = x + i2 * way(i1).x: y1 = y + i2 * way(i1).y
   IF x1 > 0 AND x1 < 16 AND y1 > 0 AND y1 < 16 THEN
    SELECT CASE q(x1, y1)
     CASE IS = 0
      q(x1, y1) = ip
      KillTest x1, y1, ip
      zi(indexzi).score = zi(indexzi).score + fenshu(index) * kt
      IF index < deep AND kt = 0 THEN
       ai x1, y1, index + 1, ip
      END IF
      q(x1, y1) = 0
      IF index = 1 THEN
       zi(indexzi).x = x1
       zi(indexzi).y = y1
       indexzi = indexzi + 1
      END IF
     CASE IS = (ip) MOD 2 + 1
      EXIT FOR
    END SELECT
   END IF
NEXT i2, i1
END SUB

SUB Ball (x AS INTEGER, y AS INTEGER, i AS INTEGER)
q(x, y) = i
MouseOff
CIRCLE (mx + (x - 1) * unit, my + (y - 1) * unit), unit / 2 - 2, (i - 1) * 15
PAINT (mx + (x - 1) * unit, my + (y - 1) * unit), (i - 1) * 15, (i - 1) * 15
MouseOn
END SUB

SUB DrawMap (clor AS INTEGER)
DIM i AS INTEGER
PAINT (100, 100), 8, 8
FOR i = 0 TO 14
  LINE (mx + i * unit, my)-STEP(0, 14 * unit), clor
NEXT i
FOR i = 0 TO 14
  LINE (mx, my + i * unit)-STEP(14 * unit, 0), clor
NEXT i
LOCATE 4, 55
PRINT "hoker.58shop.com\bbs"
LOCATE 5, 55
PRINT "scau.edu.cn"
LOCATE 6, 55
PRINT "ljxh401@sohu.com"
END SUB

SUB KillTest (x AS INTEGER, y AS INTEGER, ip AS INTEGER)
DIM i1 AS INTEGER
DIM i2 AS INTEGER
DIM i3 AS INTEGER
DIM x1 AS INTEGER
DIM y1 AS INTEGER
DIM value AS INTEGER
kt = 0
FOR i1 = 0 TO 7
  FOR i2 = 4 TO 0 STEP -1
   value = 0
   FOR i3 = 0 TO 4
    x1 = x + (i2 - i3) * way(i1).x
    y1 = y + (i2 - i3) * way(i1).y
    IF x1 > 0 AND x1 < 16 AND y1 > 0 AND y1 < 16 THEN
     IF q(x1, y1) <> ip THEN
      EXIT FOR
     END IF
    ELSE
     EXIT FOR
    END IF
   NEXT i3
   IF i3 = 5 THEN
    kt = 1
    EXIT SUB
   END IF
NEXT i2, i1
END SUB

FUNCTION MouseClick% (flag AS INTEGER)
'鼠标按键判断,参数flag=0表示检测左键,参数flag=1表示检测右键
REGS.ax = 6
REGS.bx = flag
INTERRUPT &H33, REGS, REGS
MouseClick = REGS.bx  '返回值不为0即发生事件
END FUNCTION

FUNCTION MouseMove%
'判断鼠标是否移动
'移动返回1否则返回0
REGS.ax = 11
INTERRUPT &H33, REGS, REGS
IF REGS.cx <> 0 OR REGS.dx <> 0 THEN
MouseMove = 1
ELSE
MouseMove = 0
END IF
END FUNCTION

SUB MouseOff
'屏蔽鼠标(使鼠标不可见)
REGS.ax = 2
INTERRUPT &H33, REGS, REGS
END SUB

SUB MouseOn
'打开鼠标(使鼠标可见)
REGS.ax = 1
INTERRUPT &H33, REGS, REGS
END SUB

SUB MouseSet (x AS INTEGER, y AS INTEGER, n AS INTEGER)
IF n = 1 THEN
  x = MouseX + x
  y = MouseY + y
END IF
REGS.ax = 4
REGS.cx = x  'x表示鼠标的x坐标
REGS.dx = y  'y表示鼠标的y坐标
INTERRUPT &H33, REGS, REGS
END SUB

SUB mouseTest
DIM i1 AS INTEGER
MouseSet 0, 0, 0
i1 = POINT(2, 2)
IF i1 = 0 THEN
clor = 15
ELSE
clor = 8
END IF
END SUB

FUNCTION MouseX
REGS.ax = 3
INTERRUPT &H33, REGS, REGS
MouseX = REGS.cx  '返回鼠标的x坐标
END FUNCTION

FUNCTION MouseY
REGS.ax = 3
INTERRUPT &H33, REGS, REGS
MouseY = REGS.dx  '返回鼠标的y坐标
END FUNCTION


速度很慢

5 楼

偶支持一下ljx先

6 楼

楼主辛苦可

7 楼

用数组,再算加法

8 楼

OPEN "setting.txt" FOR INPUT AS #1
中的 setting.txt在哪?

后来将它们改为
OPEN "setting.txt" FOR OUTPUT AS #1
FOR i = 1 TO 4
  PRINT #1, fenshu(i)
NEXT i
CLOSE #1
可以运行

鼠标无作用
只是下子的位置 表示不明显

9 楼

我的想法是估值。
思路可以推至一般的对弈游戏,假设此时电脑走棋,电脑模拟在每一个可放上棋子的位置放上自己的棋子,对每一个位置估值,比如如果有连五的,值最高,直接取胜了,有连四的,等等,每一个位置都进行估值,然后选取最佳的方案走棋,如果最佳方案有相同几个,再进行二次估值,就相当于电脑自己跟自己走了N回,选其中最好的一个方案走棋,当然这样下去会影响速度,一般最多就采用一两次估值。
深蓝之所以有机会战胜人,完全是因为它的运算速度快。

我来回复

您尚未登录,请登录后再回复。点此登录或注册