• Advertisement
Sign in to follow this  

My Very First Game - Made In Python - TICTACTOE

This topic is 431 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement

Congrats :)

 

Something that's initially obvious is that there is not much code reuse.

For instance rather than having player2 and player1 functions can you not use a single player function and pass in which player it is. Or reduce the amount of code in Turns, use a for loop for example. For this game it's not going to be a massive issue but as you get much larger complex code bases, avoiding duplicate code helps to make iteration much easier. This would be a great example to practice from. Just to note, the aim is not to make it in the least lines possible as that is not always beneficial and can make codebases harder to read.

Share this post


Link to post
Share on other sites

Looks nice as first game.

 

The only thing that's not pythonic in your program, is the use of semi-colon (the ";"). Python has no semi-colon at the end of a line. You do need one if you have more statements at one line, but that is quite not recommended, so in practice, you never type a semi-colon. Other languages like Java or C do use semi-colons at the end of a line, so maybe that's where you got confused.

 

 

As for improvements, they are possible if you do checking of the rows/columns separately from claiming victory:

def checkLinesPlayer1():
    if boardVal[0] == "X" and boardVal[1] == "X" and boardVal[2] == "X":
        return "yes"

    elif boardVal[3] == "X" and boardVal[4] == "X" and boardVal[5] == "X":
        return "yes"

    elif boardVal[6] == "X" and boardVal[7] == "X" and boardVal[8] == "X":
        return "yes"

    elif boardVal[0] == "X" and boardVal[4] == "X" and boardVal[8] == "X":
        return "yes"

    elif boardVal[2] == "X" and boardVal[4] == "X" and boardVal[6] == "X":
        return "yes"

    elif boardVal[0] == "X" and boardVal[3] == "X" and boardVal[6] == "X":
        return "yes"

    elif boardVal[1] == "X" and boardVal[4] == "X" and boardVal[7] == "X":
        return "yes"

    elif boardVal[2] == "X" and boardVal[5] == "X" and boardVal[8] == "X":
        return "yes"

    return "no"

def checkLinesPlayer2():
    if boardVal[0] == "o" and boardVal[1] == "o" and boardVal[2] == "o":
        return "yes"

    elif boardVal[3] == "o" and boardVal[4] == "o" and boardVal[5] == "o":
        return "yes"

    elif boardVal[6] == "o" and boardVal[7] == "o" and boardVal[8] == "o":
        return "yes"

    elif boardVal[0] == "o" and boardVal[4] == "o" and boardVal[8] == "o":
        return "yes"

    elif boardVal[2] == "o" and boardVal[4] == "o" and boardVal[6] == "o":
        return "yes"

    elif boardVal[0] == "o" and boardVal[3] == "o" and boardVal[6] == "o":
        return "yes"

    elif boardVal[1] == "o" and boardVal[4] == "o" and boardVal[7] == "o":
        return "yes"

    elif boardVal[2] == "o" and boardVal[5] == "o" and boardVal[8] == "o":
        return "yes"

    return "no"

def winnerCheck():
    timeShut = 5

    player1Won = checkLinesPlayer1()
    if player1Won == "yes":
        print("player 1 wins!")
        time.sleep(timeShut)
        sys.exit()

    player2Won = checkLinesPlayer2()
    if player2Won == "yes":
        print("player 2 wins!")
        time.sleep(timeShut)
        sys.exit()

This does the same as your winnerCheck function, but instead of testing and immediately printing, as you do, this code has separate functions "checkLinesPlayer1()" and "checkLinesPlayer2()", which return "yes" if they found a line for the player, else they return "no". In "winnerCheck", that returned result is tested, and then the player is told that he/she won.

 

Now you can see that "checkLinesPlayer1()" and "checkLinesPlayer2()" are exactly the same, except one tests for "X", and the other one tests for "o". If you pass that string into the function, you can delete one case, saving more than 20 duplicated lines:

def checkLines(player):
    if boardVal[0] == player and boardVal[1] == player and boardVal[2] == player:
        return "yes"

    elif boardVal[3] == player and boardVal[4] == player and boardVal[5] == player:
        return "yes"

    elif boardVal[6] == player and boardVal[7] == player and boardVal[8] == player:
        return "yes"

    elif boardVal[0] == player and boardVal[4] == player and boardVal[8] == player:
        return "yes"

    elif boardVal[2] == player and boardVal[4] == player and boardVal[6] == player:
        return "yes"

    elif boardVal[0] == player and boardVal[3] == player and boardVal[6] == player:
        return "yes"

    elif boardVal[1] == player and boardVal[4] == player and boardVal[7] == player:
        return "yes"

    elif boardVal[2] == player and boardVal[5] == player and boardVal[8] == player:
        return "yes"

    return "no"

def winnerCheck():
    timeShut = 5

    player1Won = checkLines("X")
    if player1Won == "yes":
        print("player 1 wins!")
        time.sleep(timeShut)
        sys.exit()

    player2Won = checkLines("o")
    if player2Won == "yes":
        print("player 2 wins!")
        time.sleep(timeShut)
        sys.exit()

Again same function as before, but now the test function is named "checkLines", and it takes a 'player' value with the string you want to test for. Now you can use the same "checkLines" function for both players, as you vary what the function tests with the "X" or "o" parameter.

Edited by Alberth

Share this post


Link to post
Share on other sites

he only thing that's not pythonic in your program, is the use of semi-colon (the ";"). Python has no semi-colon at the end of a line. You do need one if you have more statements at one line, but that is quite not recommended, so in practice, you never type a semi-colon. Other languages like Java or C do use semi-colons at the end of a line, so maybe that's where you got confused.
 

 

Thanks for all the helpful insight! I really appreciate it. I just wanted to let you know the reason I am adding the semi-colon at the end is because I want to get used to using it on other high-level languages such as Java and C#. I thought it would be a good habit to get used to.

 

THANKS FOR ALL THE HELP :)

Share this post


Link to post
Share on other sites

Congrats :)

 

Something that's initially obvious is that there is not much code reuse.

For instance rather than having player2 and player1 functions can you not use a single player function and pass in which player it is. Or reduce the amount of code in Turns, use a for loop for example. For this game it's not going to be a massive issue but as you get much larger complex code bases, avoiding duplicate code helps to make iteration much easier. This would be a great example to practice from. Just to note, the aim is not to make it in the least lines possible as that is not always beneficial and can make codebases harder to read.

 

Thanks for all the helpful feedback. It really pleases me to know that there are people out there willing to help. I had a hunch (hehe) that there was a large issue with iteration and code reusability, but it was just that I didn't know how to apply them. "Practice makes perfect" is very much true when it comes to programming. I guess its back to doing homework on what I need to work on which is EXACTLY what you guys gave me! THANKS FOR ALL THE HELP BRO

Share this post


Link to post
Share on other sites

A big logical error is that you can replace the other player's input with your own.

Fix it.

 

You might think "but it's only a small thing, and it doesn't matter that much -- the game is 90% done, isn't that good enough?", or similar, but the last 10% of any game will most likely teach you a lot.

 

You've done well to get this far, but you can do better. Learning how to finish things is a very valuable skill.

Share this post


Link to post
Share on other sites

I thought it would be a good habit to get used to.
Believe me, you will learn very fast, as those compilers tend to react violently to missing semi-colons :)

 

While languages look a lot like each other if you read them, they are in fact deeply different from each other. Trying to push a language into the ideas of another language doesn't do justice to both languages.

 

Instead, approach each language with an open mind asif it's the only language in the world, and use it like its designers aimed it to be used. It's the happiest code path, giving you the best possible quality of code in that language, and the best way to experience each language.

That in turn makes it possible to make a fair judgement between languages.

Share this post


Link to post
Share on other sites

Fix it.   You might think "but it's only a small thing, and it doesn't matter that much -- the game is 90% done, isn't that good enough?", or similar, but the last 10% of any game will most likely teach you a lot.   You've done well to get this far, but you can do better. Learning how to finish things is a very valuable skill.
@[member='Lactose'],

 

Great idea! Thank you

Share this post


Link to post
Share on other sites

 

I thought it would be a good habit to get used to.
Believe me, you will learn very fast, as those compilers tend to react violently to missing semi-colons :)

 

While languages look a lot like each other if you read them, they are in fact deeply different from each other. Trying to push a language into the ideas of another language doesn't do justice to both languages.

 

Instead, approach each language with an open mind asif it's the only language in the world, and use it like its designers aimed it to be used. It's the happiest code path, giving you the best possible quality of code in that language, and the best way to experience each language.

That in turn makes it possible to make a fair judgement between languages.

 

 

Thanks for the tip :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement