Education

Developing the basics: programming myself, post seven

tresureMap_7

How to pseudocode problem solve like a boss

<< Read the previous post in this series    Read the next post in the series>>>

Before starting to put together any new program it is best to think it all through and make sure that the problems you might come upon have been mitigated in advance.
Without putting in all the code and making sure it works as it should there is a far simpler way of tackling the problem in the first place, one which I am starting to learn and quickly realizing the benefits of. If you want to make things from scratch this is probably the best method of hitting the problems early. Pseudocode.
Pseudocode is a very high-level representation of the code. So you can put down the principle of what you need to do and work out how to do it and make sure nothing is missed. Which though it adds a bit more work at the beginning of creating the program, inevitably it will save time down the road as you will have already begun to think about how it comes together and make sure that nothing was completely overlooked.
There is actually not a real syntax for pseudocode, it is mainly for human understanding so it doesn’t need to go into so many of the details a computer would need to read it properly, so it is quicker to put together and play through without having to debug to get a result. It will help you put together the sequence you will need to follow to get the result, and also it makes it easy to visualize the process you can draw out the code and make it easier for you to see how it fits together.
As we know all computer programs are essentially an input, a process, and finally an output. So this is where you start:

INPUT
PROCESS
OUTPUT
Okay, we’re done let’s go play some PlayStation. Oh right, that isn’t really enough… unless that is what we were trying to achieve… Let’s make a plan for say a computer game like Rock, Paper, Scissors… Lizard, Spock. http://www.samkass.com/theories/RPSSL.html

INPUT
#choose between Rock, Paper, Scissors, Lizard, Spock
#opponent chooses between Rock, Paper, Scissors, Lizard, Spock

PROCESS
#Compare the inputs against each other, if/then.
#See if the player beats the other.
#Scissors cuts paper
#Paper covers Rock
#Rock crushes Lizard
#Lizard poisons Spock
#Spock smashes Scissors
#Scissors decapitate Lizard
#Lizard eats Paper
#Paper disproves Spock
#Spock vaporizes Rock
#Rock crushes Scissors

OUTPUT
#say who the winner is and why

 

Okay, this seems simple enough, right?
Output then is the simplest so let’s get that out of the way first

OUTPUT

#say who the winner is and why
Print (“The result is: ”)
print(result)

 

The input then also seems to be quite simple.
I don’t need any GUI at least for this version so there is nothing to import.
I will need a variable for each player, which will be filled with the choice they pick.

INPUT

Player1 = input(“make your choice: “)
Player2 = input(“make your choice: “)
Something like this…

 

Now it gets more tricky, but with a little effort, it should be possible to think it through, Or at least give ourselves a foundation to work off.
Process looking at what we have, we can work out that each choice can beat 2 other choices so we can start there:

PROCESS

If Player[] == Rock
If Player[] == Scissors or Lizard
Rock = str(“Rock crushes” Player[])
If Player[] == Paper
If Player[] == Rock or Spock
Paper = str(“Paper covers” Player[])
If Player[] == Scissors
If Player[] == Paper or Lizard
Scissors = str(“Scissors cut” Player[])
If Player[] == Lizard
If Player[] == Spock or Paper
Lizard = str(“Lizard bites” Player[])
If Player[] == Spock
If Player[] == Rock or Scissors
Spock = str(“Spock breaks” Player[])

Already looking at this it looks like it won’t work properly if at all, for example, there is no way to draw if the players somehow make the same choice. Plus I am not putting any result anywhere which I can call in the output. The process to is quite long and kind of repeats itself a lot.

Looking at the code in this way though, helps to see the problems before they occur and lets you think about a better way of doing the process, without wasting too much time, or flogging a dead horse as it were if you had put this into code and tried to make it work chances are you would not give up on it very easily.

So some thinking…

INPUT and OUTPUT seem fine. It is mainly the process which needs refining. The Naming leads to a lot of areas where things can go wrong. So it would be better probably if we can assign a number to each thing… so Rock = 1, Paper = 2, etc. then work out if there is some kind of pattern we can take advantage of…
Rock = 1
Paper = 2
Scissors = 3
Lizard = 4
Spock = 5

Actually, this won’t work but it is interesting as now we are coming to a whole new part of programming and luckily I have the people around to try and explain the whole idea behind how to make this work.
To make this work we need to consider the following: “for each state, the next two states are worse, and the next two states are better than it.”
What this means is you should think of the situation as a circle, So going clockwise – rock-scissors-lizard-paper-Spock.

Why?

Rock beats scissors and lizard, scissors beat lizard and paper, lizard beats paper and Spock, paper beats Spock and rock, Spock beats rock and scissors. If you look at this it makes a perfect circle and in turn creates a proper series, taking the numbers then into account:
B-A = 1 or 2 then B wins
If B-A = 3 or 4 then A wins

Try it for yourself, this works really well, add a modulo[%] to remove negative numbers and you are now cooking with gas!
You have solved a very real issue and worked out how you can implement it.

And this is the end result when you make the pseudocode into real code…

# Rock Paper Scissors Lizard Spock
#INPUT

#ergh need the random module to work
import random
player1 = input('Choose your weapon rock, paper, scissors, lizard, Spock :')

#PROCESS

#Making it work with numbers rather than words should cut down on a few bits of code
def number_into_name(number):
    if number == 0:
        return "rock"
    elif number == 1:
        return "scissors"
    elif number == 2:
        return "lizard"
    elif number == 3:
        return "paper"
    elif number == 4:
        return "Spock"
    else:
        return "Error"


def name_into_number(name):
    if name == "rock":
        return 0
    elif name == "scissors":
        return 1
    elif name == "lizard":
        return 2
    elif name == "paper":
        return 3
    elif name == "Spock":
        return 4
    else:
        print (name + "is not a character in this game... pew!")


# function which selects the winner
def rockpaperscissors(player1):

    player_number = name_into_number(player1)
    rival_number = random.randrange(0,5)
    winner = int(rival_number - player_number) % 5

    if winner >= 3:
        player_win = False
    else:
        player_win = True

    rival = number_into_name(rival_number)

    # OUTPUT
    print ("Player chooses " + player1)
    print ("Computer chooses " + rival)
    if player_win:
        print ("Player wins!\n")
    elif rival_number == player_number:
        print ("Player and computer tie!\n")
    else:
        print ("Computer wins!\n")


#ergh need to run this after it is defined... rookie error.
rockpaperscissors(str(player1))

rock paper scissors result

 

This is why we code!

 

We cannot solve our problems with the same thinking we used when we created them – Albert Einstein