LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Struggling with Tic-Tac-Toe Game in LabVIEW for a Week Now

Solved!
Go to solution

20230903_221126.png

 

I Need Advice on 5-Round Logic and AI Integration"

I've been working on a Tic-Tac-Toe game in LabVIEW for 7 days. I managed to build a basic game where players can take turns by pressing a start button and the game determines a winner. Initially, I used button arrays and numeric arrays, but switched to Picture Rings for better graphics. Now I'm dealing with 0, 1, and 2 as values, and it's really confusing. I feel like I'm close to getting it, but keep running into issues with value mismatches, making it hard to connect the dots. It's really frustrating. I'm stuck on implementing a feature where one side plays randomly (AI) and records results over 5 rounds. I keep encountering errors and can't seem to find a solution. I admit my understanding of LabVIEW is quite limited. Would anyone be willing to review my code and offer some advice? I'll attach the code file. Thank you!


 
 
 
Download All
0 Kudos
Message 1 of 20
(1,293 Views)

I haven't looked at your VI yes, but maybe you could have a look at my very old 4x4 code for some ideas.

Message 2 of 20
(1,265 Views)
Solution
Accepted by topic author zubat18@gmail.com

Sorry, I currently cannot inspect your code because I only have LabVIEW 2020 on my laptop here. Consider "save for previous" before attaching. Also make sure that it is runnable and includes all dependencies such as subVIs and sound files.

 

Also explain what the difference between the two attached VIs are.

 

Just looking at your code picture, you seem to be completely missing the spirit and power of dataflow. I am guessing you are a text programmer and retain habits that are basically wrong here. Maybe you should start with some tutorial.

 

You seem to have all controls and indicators disconnected, then shuffling all logic around with value references and local variables. none of those are needed!!! In LabVIEW, the wire is the variable and data that needs to be maintained across iterations belongs in shift registers. You have glaring race conditions. Properly programmed, you code could easily fit on half a postcard.

Message 3 of 20
(1,263 Views)

I've downgraded the version.

I also realized that I need to resolve the issue with the WAV file paths.

 

V1 is functional but lacks AI capabilities and a detailed case structure.

V2 is not operational; I was attempting to account for every possible scenario through various cases.

 

I've looked at a variety of samples in LabVIEW, including 4x4 grids and three-level difficulty AI. While they are impressive, simplifying the more complex versions to fit my needs has proven to be quite challenging. Right now, I'm trying to build upon a simpler version, but even that isn't easy.

 
 
 
0 Kudos
Message 4 of 20
(1,213 Views)

So what's the difference between V1 and V2?

 

I recommend to use relative paths (relative to the current VI) for the sound files. It is unlikely that most users have folders in a "C:\Users\zubat\OneDrive\Desktop\TTT\... " hierarchy.

Message 5 of 20
(1,209 Views)

V1 is functional but lacks AI capabilities and a detailed case structure.

V2 is not operational; I was attempting to account for every possible scenario through various cases.

 
0 Kudos
Message 6 of 20
(1,197 Views)

No, V1 is NOT functional by any definition of the term. 😄

 

  • Tiles should be indicators so you don't need to discard the mouse down event.
  • Since your X button is outside the loop, the loop cannot be stopped with it. If you want to act on it, the terminal needs to be inside the loop.
  • Your game counter should be an integer, right?
  • Most of your controls should be indicators because the code controls their content. (
  • Your code is full of Rube Goldberg constructs, for example your "equal true?" can be replaced by a simple wire (see picture below)!

 

 

altenbach_0-1693780398854.png

To get you started, here's a quick rewrite of the basic functionality. Just add a subVI to score the board and returns: Xwins, OWins, Tied, or "keep playing", for example. Depending on the outcome you can then increment counters held in shift registers (not shown).

I strongly recommend to get rid of all these silly sounds. That's the very last thing to add once the code works.

Message 7 of 20
(1,190 Views)

@altenbach wrote:

Just add a subVI to score the board .


Here's a very simple draft how it could be done:

 

altenbach_0-1693782481906.png

 

Message 8 of 20
(1,184 Views)

20230904_184353.png

 

Thanks to you, I've been able to progress this far after about 4 hours of tinkering. What I'm unsure about now is what kind of structure (event or case) would be best for implementing a Player 2 AI that makes random moves. After the player clicks and selects a value, I need the AI to randomly choose one spot among the spots with a value of '2'. I'm not sure how to best implement this feature. Should I implement it as another case structure within the central case structure labeled '2' that triggers depending on the player's turn? I'm also wondering how to continue the game for up to 5 rounds while recording the score of the player.

 
 
 
0 Kudos
Message 9 of 20
(1,149 Views)

You again failed to "save for previous" before attaching, so I cannot look at it until later. Also never (never ever!) attach new code with the same name as the old code! That can cause a lot of confusion because the browser will rename the files to keep them unique (e.g. "TTT (1).zip") and it is confusing to remember what's what.

 

From what I can see from the picture, you are still falling into your old habits using terminals as "variable" and read/write to them using locals. This blurs the distinction between control and indicator and can cause race conditions because it is not obvious to see what wrote to it last! (when programmed with wires, you can just "follow the wire" to see where the value comes from and what depends on it. Much cleaner!)  For example why is the "winner" terminal disconnected? If you would place it after the case structure, you can output different strings from different cases (even empty strings!) to the same terminal. no locals needed!

 

Your counts belong in a shift register that you update in the relevant cases, not ping-ponged around via locals.

 

You don't need the big index array for the sound paths resulting in many wires going into the rest. Just wire the array into the code and index one where needed and play that sound.

 

Message 10 of 20
(1,119 Views)