• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Frits Walraven
Bartenders:
  • Carey Brown
  • salvin francis
  • Claude Moore

TicTacToe Game  RSS feed

 
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After being contacted personal by the poster of this thread here on the forum with the question to help here, I decided to write my own take on the TicTacToe game, but hit a snare. I have no errors, which means there is a problem with the logic, which is always way harder to solve. I can't really debug the code, cause when in debug mode my Jpanel is not being showed so the part where the problem lies isn't being executed. My guess is that the problem lies in how I check for winning combinations.
Let me set the scene. I have a Jframe containing a JPanel with a gridLayout of 3x3, in the JPanel I add 9 buttons on which I set an actionListener.
When the button is clicked I set an ImageIcon containing an x or an o image, based on which player's turn it is and the actionListener is removed from the button(preventing overwritting).
To check if a winning combination is formed I check if the path of the three buttons in the combination contains an x or an o (again based on the player's turn)
But somehow somethimes the method I use for that return true when it shouldn't announcing a false winner.
To you guess prefer to see the full code or only the methods I use to check?
I start of with the methods, maybe someone here can see what I'm missing:
 
Bartender
Posts: 700
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Recheck your logic for wins. You return true for (0,5,8) but shouldn't that be (0,4,8)
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
no it should'nt 0 5 and 8 is dioginal from left upper to right botomcorner
 
Ranch Hand
Posts: 59
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Demesmaecker wrote:no it should'nt 0 5 and 8 is dioginal from left upper to right botomcorner



are you sure?
 
Marshal
Posts: 6684
464
BSD Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
012
345
678
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whoeps... I don't know why I thought it was 5... I acounted for starting at zero and ended at 8...
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's still an error though, if I have x's on 0 and 4 and o's on 2 and 8 it still returns true, which should be imposible since I only have 2 of each
 
Liutauras Vilda
Marshal
Posts: 6684
464
BSD Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Looking to comment of the method + its implementation, it seems it returns true if there is either 'x' or 'o'?

I find it confusing. What the 'content' represents?
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's a two player game, for player1 it's x for player2 it's o
 
Liutauras Vilda
Marshal
Posts: 6684
464
BSD Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If can't find the bug, then I'd start refactoring and making logic simpler to understand.

Then would gradually move towards making it more object oriented.
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I actually already refactored it a bit, first I had the if, all the if else and the else in one big if() stringing them with || and ok it might be eaiser to read, but it dosn't change the logic, the sucky thing is I can't debug the code, so I can't see what's going on in the if statements, I can only see that content is correct
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you mean by making it more object oriented, we're talking about components, they're allready objects no?
 
Liutauras Vilda
Marshal
Posts: 6684
464
BSD Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Demesmaecker wrote:What do you mean by making it more object oriented, we're talking about components, they're allready objects no?


I don't get why you debugging from the front-end side? Doesn't make sense to make game logic first, test it, and only then plug in gui?
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At one point the logic worked, when I come to think about it the problem might actually not be in that part, but in the last part I implemented, being:
 
Liutauras Vilda
Marshal
Posts: 6684
464
BSD Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'd tackle problem exactly in the same way as did with the game's logic part - by refactoring it.

In my subjective opinion the playGame() method is hard to follow as its flow isn't obvious.
 
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Someone help me with my code! I was the one who asked him to help me, please click on the hyperlink!
 
Marshal
Posts: 13441
222
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know it's a small program but it still clearly shows the problem of mixing display concerns with problem domain concerns.

Having a call to frame.dispose() inside a method like playGame() tightly couples the display logic to the main game loop. The problem with doing this becomes immediately apparent if we decide to play this game on a web page instead. Or you want to just use a terminal window with plain text input/output. Instead of having to just change some display-specific logic, you have to now mess around with the code that controls the game flow. That's bad.

Here's an alternative (I posted something similar to this code in the other thread you originally cited):

This code is not concerned in any way with how the state of the game is display or how the results are declared. The intent of this code never changes, no matter how you are displaying things to the user. If you need to change the way things are displayed, you don't have to mess with this logic. Instead, you go and (maybe) change the show(), declareWinner(), and declareDraw() methods.
 
Marshal
Posts: 64089
215
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ana Yo wrote:. . . I was the one who asked him to help me . . .

Pleae read this. Please ask the question on your thread. And have you answered the questions I asked you yesterday?
 
Campbell Ritchie
Marshal
Posts: 64089
215
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . a call to . . . tightly couples the display logic to the main game loop.  . . .

So does the use of icons on buttons. Testing which icon is on which button, particularly with numbers like 1 and 2, couples the game logic to the display, and also puts the cart before the horse. The idea of a GUI is to display what the state of the game is, but here it determines what the state of the game is. As we have already seen, the use of magic numbers can be error‑prone.

Also, the logic of the methods for testing for a winner doesn't accurately mirror how the game is played in real life. Nor is there any need to find the winning player, because that is already known.
I would prefer this sort of method name:- while (game.inProgress()) ...
I can see problems with a getWinner() method; what is that method going to do when there is no winner yet, and when there are still vacant squares?

Anyway, I shall let you think about that; I am not providing complete code, not even to experienced people like those on this thread
 
Junilu Lacar
Marshal
Posts: 13441
222
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I can see problems with a getWinner() method; what is that method going to do when there is no winner yet, and when there are still vacant squares?


What problems do you see?

Let's assume the return value is a String or char, then in those conditions it seems perfectly acceptable to expect " " or ' ' (blank/space) for a winner if the only possible values for an actual winner are "X" and "O", right?

On the other hand, if the return value were some kind of enum, like a TicTacToe.Player, then I would think that either Player.NONE or null would be a reasonably acceptable return value to indicate that there is no winner at a particular point in the game.

Neither of these really presents a huge design problem. At any rate, those aren't really problems that the given game logic would create anyway. As a programmer, it's important to exercise due diligence but that has to be balanced with economics in mind. So rather than making the program as robust as possible, I prefer to make it as robust as necessary. This nuance keeps my inner gold-plater in check. Do I really need to spend extra effort worrying about those things if I know that the only time I'll need to query for a game winner is when it has already been determined that there is one? The most I should have to do is to double check the precondition and return a default value if it is not met. Like so:


Or if you are using an enum:
 
Junilu Lacar
Marshal
Posts: 13441
222
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I would prefer this sort of method name:- while (game.inProgress()) ...


I'm guessing that you're coming from the perspective that this code:

is more difficult to read. I agree, the use of the negation operator (!) in this case increases cognitive load. However, I don't think game.notOver() or even game.isNotOver() has the same problem. That reads very naturally to me because that's exactly how I would talk about the logic in plain English. On the other hand, I am less inclined to talk about the same in idea in terms like "While the game is in progress..." I don't know, maybe it's a left-handed vs right-handed thing.

The difference, I think, is that when you use the ! operator, your brain still has to translate that to "not" and then interpret it whereas with a name like "notOver()" there is no translation involved: you simply interpret the idea.
 
Junilu Lacar
Marshal
Posts: 13441
222
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Regarding (!game.over()) vs. (game.notOver()), I think the same lack of translation from ! to "not" is evident in other APIs like in JUnit, for example:

These also read very naturally and are unencumbered by the cognitive load that the "!" operator would otherwise impose on the reader.
 
Campbell Ritchie
Marshal
Posts: 64089
215
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . you're coming from the perspective that this code: . . . is more difficult to read

Yes.

. . . . with a name like "notOver()" there is no translation involved . . .

Point taken.
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since there is a lot of discussion about how the code is written and some things don't seem to be clare let me post the full code, it's true that somethings, if this would be a personal project I would have done differently, but I adjusted the style to the assignment, the get winne method was actually the assignment and it had to return a String. And yes Junilu you're right, incase there isn't a winner yet it simply returns null
 
Campbell Ritchie
Marshal
Posts: 64089
215
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why have you only got one class?
 
Daniel Demesmaecker
Rancher
Posts: 1170
18
Firefox Browser Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
cause I was lazy and it was ment as a quick example
and I actualy have 2, I also have an objectclass for player
 
Campbell Ritchie
Marshal
Posts: 64089
215
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Demesmaecker wrote:cause I was lazy . . .

Hahahahahahahahahahaha!

Have a +1 for honesty and making me laugh!

Right: let's let you out of your misery about one of the things I think. You do not need to work out who won the game because you already know. The winning player is the same person as the current player when the game completes with a full row XXX or OOO.
Using that hint, work out how you can sometimes determine that a game is complete with a winning row by examining one row and one column. You sometimes also have to inspect diagonals.
 
"How many licks ..." - I think all of this dog's research starts with these words. Tasty tiny ad:
ScroogeXHTML - the small and fast RTF to HTML converter library
https://coderanch.com/t/707504/ScroogeXHTML-RTF-HTML-XHTML-converter
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!