1

This is a bit of a follow-up question to my post here. I'm now attempting to replicate the same general code using Connect Four (7x6 grid instead of 3x3).

However, when I pass a Dynamic value to my createBox function, it seems to use values such as board$3379[[1,6]] instead of using the actual board variable. I believe this relates to the RuleDelayed issue described here but using With doesn't seem to help.

When I remove the Dynamic function before board[[x,y]] it works as intended.

createBox[elem_] := Module[{},
   Print@elem;
   Graphics[
    {{White, Rectangle[]}
     , Switch[elem
      , "A", {Red, Disk[{0.5, 0.5}, 0.4]}
      , "B", {Blue, Disk[{0.5, 0.5}, 0.4]}
      , " ", {Thick, Circle[{0.5, 0.5}, 0.4]}
      , _, {}
      ]
     }, ImageSize -> 50, Frame -> True, FrameStyle -> Thickness[.02], 
    FrameTicks -> None
    ]
   ];

CreateDialog[
  DynamicModule[
   {board = ConstantArray[" ", {7, 6}], player = "A"},
   Grid[
    Table[
     With[{y = y, x = x}
      , EventHandler[
       createBox[Dynamic@board[[x, y]]]
       , {"MouseClicked" :> (
          If[board[[y, x]] === " ",
            board[[x, y]] = "A";
            ];
          )}
       ]]
     , {y, Length@board[[1]], 1, -1}, {x, Length@board}
     ], Spacings -> {0, 0}
    ]
   ], WindowTitle -> "Connect Four", WindowSize -> All
  ];

Is there a better way to structure this?

Chris
  • 55
  • 4

1 Answers1

1

I'm puzzled about what your code is really attempting to do because it only allows white circles to be changed to red disks. There is no way to get a blue disk and no logic for two players to interact. However, look at the following code, it may give you an idea on how to proceed.

Basically, what I have done is remove Module from createBox and move the wrapper Dynamic that you place around board to wrap createBox, so the front-end will deal with it. That seems to fix what I see as your principal problems.

createBox[elem_] :=
  Graphics[
    {{White, Rectangle[]},
     Switch[elem,
       "A", {Red, Disk[{0.5, 0.5}, 0.4]},
       "B", {Blue, Disk[{0.5, 0.5}, 0.4]},
       " ", {Thick, Circle[{0.5, 0.5}, 0.4]},
       _, {}]},
    ImageSize -> 50,
    Frame -> True,
    FrameStyle -> Thickness[.02],
    FrameTicks -> None]

CreateDialog[
  DynamicModule[{board = ConstantArray[" ", {7, 6}], player = "A"},
  Grid[
    Table[
      With[{y = y, x = x},
        EventHandler[
          Dynamic @ createBox[board[[x, y]]], 
          {"MouseClicked" :> 
             (If[board[[y, x]] === " ", board[[x, y]] = "A"])}]], 
      {y, Length @ board[[1]], 1, -1}, {x, Length @ board}],
    Spacings -> {0, 0}]],
  WindowTitle -> "Connect Four",
  WindowSize -> All];

dialog

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • The code doesn't make a whole lot of sense right now, should have clarified; right now I'm just testing click interaction but later it can be a state of red, blue, or empty. I could have sworn I tried your solution but it works great. Thanks! – Chris Jan 01 '18 at 04:37
  • 1
    @Chris. I'm glad this was a help to you, and thanks for accepting the answer, but I'm surprised you that you didn't up-vote it as well. Rather unusual for someone to accept but not up-vote. – m_goldberg Jan 01 '18 at 17:14
  • Sorry, slipped my mind. – Chris Jan 01 '18 at 21:08