Author Topic: '5 ball' - logic game AMOEBA?  (Read 3177 times)

0 Members and 1 Guest are viewing this topic.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
'5 ball' - logic game AMOEBA?
« on: January 05, 2022, 06:49:29 pm »
Hi !
You must know that there is a logic game where 5 identical balls have to be unloaded by 2 players. Vertically, horizontally, or diagonally. (OX, othello, 5 ball ???) Known as a lot. We called it “amoeba” because when we played it in the booklet at school, it looked like that.
I found a very simple algorithm. Not professional, but persistent and fun. If you know a professional algorithm, send it to me.
I created an interface for it.

Code: QB64: [Select]
  1. '5 ball MasterGy 2022
  2. DIM SHARED colors(9) AS _INTEGER64, map_s
  3.  
  4.  
  5. '-------- SETTINGS
  6. monx = 1000 'windows X size
  7. colors(0) = _RGB32(255, 50, 50) 'player1 color - ME
  8. colors(1) = _RGB32(50, 50, 255) 'player2 color - COMPUTER
  9. tsq_size = 25 '1 square texture size
  10. ball_rad = .6 'ball size
  11. map_s = 100 'XxX map size
  12. pos_z = 5 'zoom map
  13. near = 3 'test field empty field full field distance
  14. text_h = monx * .05
  15. '------------------
  16.  
  17.  
  18.  
  19. 'MAP_MEM array 0 original balls ,1 winner color foggy area, 2 winner-puppet sin signal
  20.  
  21. txt_text(0) = txt_to_text("I WANT TO PLAY !!!-ENTER       exit-ESC")
  22. txt_text(1) = txt_to_text("BOARD ZOOM - mousewheel   BOARD MOVING - mouse right button and moving")
  23. txt_text(2) = txt_to_text("BACK-backspace TIP-T button EMPTY BOARD-E button")
  24.  
  25.  
  26. 'map texture
  27. temp = _NEWIMAGE(tsq_size, tsq_size, 32): _DEST temp: CLS , _RGB32(100, 100, 200)
  28. marg = tsq_size * .07: LINE (marg, marg)-(tsq_size - marg, tsq_size - marg), _RGB32(200, 200, 200), BF: text(0) = _COPYIMAGE(temp, 33): _FREEIMAGE temp
  29. 'balls and foggy texture
  30. FOR ac = 0 TO 1: temp = _NEWIMAGE(tsq_size, tsq_size, 32): _DEST temp: CLS: PAINT (0, 0), _RGB32(10, 10, 10)
  31.     CIRCLE (tsq_size / 2, tsq_size / 2), tsq_size * ball_rad / 2, colors(ac): PAINT (tsq_size / 2, tsq_size / 2), colors(ac), colors(ac)
  32.     _CLEARCOLOR _RGB32(10, 10, 10): text(1 + ac) = _COPYIMAGE(temp, 33)
  33.     IF ac = 0 THEN _SETALPHA 100, colors(ac), temp: text(9) = _COPYIMAGE(temp, 33)
  34.     _FREEIMAGE temp
  35.  
  36.     temp = _NEWIMAGE(20, 20, 32): _DEST temp: PAINT (0, 0), colors(ac), colors(ac): _SETALPHA 100, colors(ac), temp
  37. text(4 + ac) = _COPYIMAGE(temp, 33): _FREEIMAGE temp: NEXT ac
  38. 'map near texture
  39. temp = _NEWIMAGE(tsq_size, tsq_size, 32): _DEST temp: CLS , _RGB32(100, 100, 200)
  40. marg = tsq_size * .05: LINE (marg, marg)-(tsq_size - marg, tsq_size - marg), _RGB32(100, 100, 100), BF: text(3) = _COPYIMAGE(temp, 33): _FREEIMAGE temp
  41.  
  42.  
  43. 'preparation
  44. DIM steps(map_s * map_s - 1, 2) '0- 1 or 2 ,1-x, 2-y
  45. mony = monx / 16 * 9: mon = _NEWIMAGE(monx, mony, 32): SCREEN mon: pos_x = (monx - (pos_z * map_s)) / 2: pos_y = (mony - (pos_z * map_s)) / 2
  46. REDIM SHARED map_mem(map_s - 1, map_s - 1, 9)
  47.  
  48.  
  49.  
  50. DO: _LIMIT 50: winsin = winsin + .2: winsin_n = SIN(winsin) * pos_z * .1 'winner puppets sin
  51.     'moving and zooming map
  52.     mousew = 0: WHILE _MOUSEINPUT: mousew = mousew + _MOUSEWHEEL: WEND: apos_x = (_MOUSEX - pos_x) / (pos_z * map_s): apos_y = (_MOUSEY - pos_y) / (pos_z * map_s)
  53.     on_the_map = apos_x > 0 AND apos_x < 1 AND apos_y > 0 AND apos_y < 1
  54.     IF on_the_map THEN
  55.         pos_x = pos_x - (move_x - _MOUSEX) * ABS(_MOUSEBUTTON(2) AND mb2_last): pos_y = pos_y - (move_y - _MOUSEY) * ABS(_MOUSEBUTTON(2) AND mb2_last)
  56.         IF _MOUSEBUTTON(2) THEN move_x = _MOUSEX: move_y = _MOUSEY
  57.         mb2_last = _MOUSEBUTTON(2): pos_z = pos_z - mousew * 1.5: IF pos_z < 5 THEN pos_z = 5 ELSE IF pos_z > 60 THEN pos_z = 60
  58.         apos_x2 = (_MOUSEX - pos_x) / (pos_z * map_s): apos_y2 = (_MOUSEY - pos_y) / (pos_z * map_s)
  59.         mousew = (pos_z * map_s) * SGN(ABS(mousew)): pos_x = pos_x + (apos_x2 - apos_x) * mousew: pos_y = pos_y + (apos_y2 - apos_y) * mousew
  60.     END IF
  61.     pos_xa = pos_xa + (pos_x - pos_xa) * .1: pos_ya = pos_ya + (pos_y - pos_ya) * .1: pos_za = pos_za + (pos_z - pos_za) * .1: mon_limit = monx * .05
  62.     IF pos_xa + (map_s - 1) * pos_za < mon_limit THEN pos_xa = mon_limit - ((map_s - 1) * pos_za) + mon_re: pos_x = pos_xa
  63.     IF pos_xa > monx - mon_limit THEN pos_xa = monx - mon_limit - mon_re: pos_x = pos_xa
  64.     IF pos_ya + (map_s - 1) * pos_za < mon_limit THEN pos_ya = mon_limit - ((map_s - 1) * pos_za) + mon_re: pos_y = pos_ya
  65.     IF pos_ya > mony - mon_limit THEN pos_ya = mony - mon_limit - mon_re: pos_y = pos_ya
  66.  
  67.  
  68.     'fill map array
  69.     REDIM SHARED map(map_s - 1, map_s - 1, 9): FOR a = 0 TO steps_c - 1: map(steps(a, 1), steps(a, 2), 0) = steps(a, 0): NEXT a
  70.     FOR a = 0 TO steps_c - 1: FOR tx2 = -near TO near: FOR ty2 = -near TO near: IF tx2 = 0 AND ty2 = 0 THEN _CONTINUE
  71.                 px = tx2 + steps(a, 1): py = ty2 + steps(a, 2): IF px < 0 OR px > map_s - 1 OR py < 0 OR py > map_s - 1 THEN _CONTINUE
  72.     map(px, py, 1) = ABS(map(px, py, 0) = 0) AND ABS(map_mem(px, py, 1) = 0): NEXT ty2, tx2, a
  73.  
  74.     'draw map
  75.     FOR tx = 0 TO map_s - 1: FOR ty = 0 TO map_s - 1
  76.             x1 = pos_xa + tx * pos_za: x2 = x1 + pos_za: y1 = pos_ya + ty * pos_za: y2 = y1 + pos_za: atext = text(0): ww = winsin_n * map_mem(tx, ty, 2)
  77.             _PUTIMAGE (x1, y1)-(x2, y2), atext, , , _SMOOTH
  78.             IF steps_c THEN IF steps(steps_c - 1, 1) = tx AND steps(steps_c - 1, 2) = ty AND ls_step > 0 AND step_flash THEN _CONTINUE
  79.             IF map(tx, ty, 0) THEN _PUTIMAGE (x1 - ww, y1 - ww)-(x2 + ww, y2 + ww), text(map(tx, ty, 0)), , , _SMOOTH
  80.             IF map_mem(tx, ty, 0) THEN _PUTIMAGE (x1 - ww, y1 - ww)-(x2 + ww, y2 + ww), text(map_mem(tx, ty, 0)), , , _SMOOTH
  81.             IF map_mem(tx, ty, 1) THEN _PUTIMAGE (x1, y1)-(x2, y2), text(4 + map_mem(tx, ty, 1) - 1), , , _SMOOTH
  82.     NEXT ty, tx
  83.  
  84.     IF on_the_map THEN real_x = INT(map_s * apos_x): real_y = INT(map_s * apos_y) 'which block is the mouse on?
  85.     REDIM c(2): FOR tx = 0 TO map_s - 1: FOR ty = 0 TO map_s - 1: c(map(tx, ty, 0)) = c(map(tx, ty, 0)) + 1: NEXT ty, tx 'how many balls
  86.  
  87.     'draw putty if need
  88.     IF on_the_map AND c(2) >= c(1) AND connect_game AND _MOUSEBUTTON(2) = 0 THEN
  89.         elt = pos_za / 2 + winsin_n
  90.         _PUTIMAGE (_MOUSEX - elt, _MOUSEY - elt)-(_MOUSEX + elt, _MOUSEY + elt), text(9), , , _SMOOTH
  91.     END IF
  92.  
  93.  
  94.     map(0, 0, 8) = 0: calculation 'calculating the best move for both players
  95.  
  96.     'draw tip
  97.     IF (_KEYDOWN(ASC("t")) OR _KEYDOWN(ASC("T"))) AND INT(2 * RND(1)) AND connect_game THEN
  98.         x1 = pos_xa + map(0, 0, 4) * pos_za: x2 = x1 + pos_za: y1 = pos_ya + map(0, 0, 5) * pos_za: y2 = y1 + pos_za
  99.         _PUTIMAGE (x1, y1)-(x2, y2), text(1), , , _SMOOTH
  100.     END IF
  101.  
  102.  
  103.  
  104.  
  105.  
  106.     IF c(1) > c(2) THEN 'who's next?
  107.         steps(steps_c, 0) = 2: steps(steps_c, 1) = map(0, 0, 6): steps(steps_c, 2) = map(0, 0, 7): steps_c = steps_c + 1 'COMPUTER MOVING
  108.     ELSE
  109.         IF connect_game THEN
  110.             IF on_the_map AND _MOUSEBUTTON(1) AND mb1_last = 0 THEN
  111.                 IF map(real_x, real_y, 0) = 0 AND map_mem(real_x, real_y, 1) = 0 THEN
  112.                     steps(steps_c, 0) = 1: steps(steps_c, 1) = real_x: steps(steps_c, 2) = real_y: steps_c = steps_c + 1
  113.                 END IF
  114.             END IF
  115.             mb1_last = _MOUSEBUTTON(1): IF bill$ = CHR$(8) AND steps_c > 3 THEN steps_c = steps_c - 2
  116.         ELSE
  117.             IF steps_c = 0 THEN
  118.                 empty = 5: DO: x = INT(map_s * RND(1)): y = INT(map_s * RND(1)): no_ok = 0: FOR tx = -empty TO empty: FOR ty = -empty TO empty
  119.                             px = x + tx: py = y + ty: IF px < 0 OR px > map_s - 1 OR py < 0 OR py > map_s - 1 THEN no_ok = 1: _CONTINUE
  120.                 no_ok = no_ok OR SGN(map_mem(px, py, 1)): NEXT ty, tx: LOOP WHILE no_ok
  121.                 steps(steps_c, 0) = 1: steps(steps_c, 1) = x: steps(steps_c, 2) = y: steps_c = steps_c + 1
  122.             ELSE
  123.                 steps(steps_c, 0) = 1: steps(steps_c, 1) = map(0, 0, 4): steps(steps_c, 2) = map(0, 0, 5): steps_c = steps_c + 1
  124.             END IF
  125.         END IF
  126.     END IF
  127.  
  128.  
  129.     'text control
  130.     th = text_h / _HEIGHT(txt_text(1)) * _WIDTH(txt_text(1)): x1 = (monx - th) / 2: x2 = x1 + th: y1 = mony - text_h: y2 = mony
  131.     _PUTIMAGE (x1, y1)-(x2, y2), txt_text(1), , , _SMOOTH
  132.  
  133.     IF connect_game THEN
  134.         th = text_h / _HEIGHT(txt_text(2)) * _WIDTH(txt_text(2)): x1 = (monx - th) / 2: x2 = x1 + th: y1 = 0: y2 = text_h
  135.         _PUTIMAGE (x1, y1)-(x2, y2), txt_text(2), , , _SMOOTH
  136.     ELSE
  137.         th = text_h / _HEIGHT(txt_text(0)) * _WIDTH(txt_text(0)): x1 = (monx - th) / 2: x2 = x1 + th: y1 = 0: y2 = text_h
  138.         _PUTIMAGE (x1, y1)-(x2, y2), txt_text(0), , , _SMOOTH
  139.     END IF
  140.  
  141.  
  142.     _DISPLAY: CLS , _RGB32(30, 0, 0)
  143.  
  144.  
  145.  
  146.     IF map(0, 0, 8) THEN 'one player won!
  147.         fill = 2: FOR tx = 0 TO map_s - 1: FOR ty = 0 TO map_s - 1: IF map(tx, ty, 0) = 0 THEN _CONTINUE
  148.                 map_mem(tx, ty, 0) = map(tx, ty, 0): FOR tx2 = -fill TO fill: FOR ty2 = -fill TO fill
  149.                         px = tx2 + tx: py = ty2 + ty: IF px < 0 OR px > map_s - 1 OR py < 0 OR py > map_s - 1 THEN _CONTINUE
  150.         map_mem(px, py, 1) = map(0, 0, 8): NEXT ty2, tx2, ty, tx: steps_c = 0
  151.         winner_table = winner_table + 1: IF winner_table = 10 THEN winner_table = 0: REDIM SHARED map_mem(map_s - 1, map_s - 1, 9)
  152.     END IF
  153.  
  154.  
  155.     bill$ = LCASE$(INKEY$)
  156.     IF bill$ = CHR$(13) AND connect_game = 0 THEN connect_game = 1: steps_c = 0
  157.     IF bill$ = CHR$(27) THEN IF connect_game THEN connect_game = 0: pos_z = 5: pos_x = (monx - (pos_z * map_s)) / 2: pos_y = (mony - (pos_z * map_s)) / 2 ELSE SYSTEM
  158.     IF bill$ = "e" THEN REDIM SHARED map_mem(map_s - 1, map_s - 1, 9)
  159.  
  160.     'last step flash
  161.     IF steps_c <> l_steps_c THEN ls_step = 10
  162.     l_steps_c = steps_c: ls_step = ls_step - 1: step_flash = step_flash XOR 1
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173. SUB calculation
  174.     REDIM d(3, 1), xval(4), p(1, 4): d(0, 0) = 0: d(0, 1) = 1: d(1, 0) = 1: d(1, 1) = 1: d(2, 0) = 1: d(2, 1) = 0: d(3, 0) = -1: d(3, 1) = 1
  175.     xval(1) = 565: xval(2) = 2130: xval(3) = 7483: xval(4) = 43848
  176.  
  177.     'winning search
  178.     FOR tx = 0 TO map_s - 1: FOR ty = 0 TO map_s - 1: IF map(tx, ty, 0) = 0 THEN _CONTINUE
  179.             FOR ad = 0 TO 3: FOR av = 0 TO 4: REDIM c(2) AS _BYTE: FOR av2 = -4 TO 0
  180.                         p(0, ABS(av2)) = d(ad, 0) * (av + av2) + tx: p(1, ABS(av2)) = d(ad, 1) * (av + av2) + ty
  181.                         IF p(0, ABS(av2)) < 0 OR p(0, ABS(av2)) > map_s - 1 OR p(1, ABS(av2)) < 0 OR p(1, ABS(av2)) > map_s - 1 THEN _CONTINUE
  182.                     c(map(p(0, ABS(av2)), p(1, ABS(av2)), 0)) = c(map(p(0, ABS(av2)), p(1, ABS(av2)), 0)) + 1: NEXT av2: winner = ABS(c(1) = 5) + ABS(c(2) = 5) * 2
  183.                     IF winner THEN FOR ax = 0 TO 4: map_mem(p(0, ax), p(1, ax), 2) = 1: NEXT ax: map(0, 0, 8) = winner: EXIT SUB
  184.     NEXT av, ad, ty, tx
  185.  
  186.     'most effective steps
  187.     REDIM max(1): FOR tx = 0 TO map_s - 1: FOR ty = 0 TO map_s - 1: IF map(tx, ty, 1) = 0 OR map_mem(tx, ty, 1) THEN _CONTINUE
  188.             REDIM line_val(1), lv(1): FOR ad = 0 TO 3: FOR av = 0 TO 4: REDIM c(2) AS _BYTE: FOR av2 = -4 TO 0
  189.                         px = d(ad, 0) * (av + av2) + tx: py = d(ad, 1) * (av + av2) + ty: IF px < 0 OR px > map_s - 1 OR py < 0 OR py > map_s - 1 THEN _CONTINUE
  190.                     c(map(px, py, 0)) = c(map(px, py, 0)) + 1: NEXT av2: IF c(2) THEN lv(0) = 0 ELSE lv(0) = xval(c(1))
  191.                     IF c(1) THEN lv(1) = 0 ELSE lv(1) = xval(c(2))
  192.             line_val(0) = line_val(0) + lv(0): line_val(1) = line_val(1) + lv(1): NEXT av, ad
  193.             FOR ax = 0 TO 1: map(tx, ty, 2 + ax) = line_val(ax) * 1.7 + line_val(ax XOR 1) + 3 * RND(1)
  194.                 IF map(tx, ty, 2 + ax) > max(ax) THEN max(ax) = map(tx, ty, 2 + ax): map(0, 0, 4 + ax * 2) = tx: map(0, 0, 5 + ax * 2) = ty
  195.     NEXT ax, ty, tx
  196.  
  197. FUNCTION txt_to_text (x$): _FONT 16: marg = 10: temp = _NEWIMAGE(8 * LEN(x$) + 2 * marg, 16 + marg * 2, 32): _DEST temp: CLS , _RGBA32(0, 0, 0, 150)
  198. COLOR _RGB32(255, 255, 255), 0: _PRINTSTRING (marg, marg), x$: txt_to_text = _COPYIMAGE(temp, 33): _FREEIMAGE temp: END FUNCTION

 
amoba.jpg