Because the code you write is to be used for teaching, the importance is not on performance, but on correctness and readability and understandability (comphrensiveness?).
So basically...
Add comments! Explain each step, so that the kids are gonna see the code, think "what does it do", and they can read it right there!
Don't use dx
and dy
, use more explanatory variables!
Let's combine them:
if dx == x and dy == y:
if moves == 1:
print('You died in', moves,'move!')
elif moves > 1 or moves == 0:
print('You died in', moves,'moves!')
break
elif cx == x and cy == y:
if moves == 1:
print('You won in', moves,'move!')
elif moves > 1 or moves == 0:
print('You won in', moves,'moves!')
break
This is hard to understand. dx
and dy
were hard to grasp at first - when doing games programming, usually dx
and dy
are "delta-x" and "delta-y", to calculate object velocity.
But it's dragon x y and chest x y here!
So just call it that.
if dragon_x == x and dragon_y == y:
if moves == 1:
print('You died in', moves,'move!')
elif moves > 1 or moves == 0:
print('You died in', moves,'moves!')
break
elif chest_x == x and chest_y == y:
if moves == 1:
print('You won in', moves,'move!')
elif moves > 1 or moves == 0:
print('You won in', moves,'moves!')
break
Next, I'd usually tell you to split this up into functions. But maybe these kids don't know functions yet, and it's remarkably frustrating to be shown "the solution" when "the solution" consists of "this magic trick I didn't teach you yet, haha".
Use comments instead, and be sure to teach them what a comment is and what its for. If you have to review homework, a comment might be all you get to understand their code.
#check for loss by comparing dragon and player location
if dragon_x == x and dragon_y == y:
if moves == 1:
print('You died in', moves,'move!')
elif moves > 1 or moves == 0:
print('You died in', moves,'moves!')
break
#else, check for victory by comparing chest and player location
elif chest_x == x and chest_y == y:
if moves == 1:
print('You won in', moves,'move!')
elif moves > 1 or moves == 0:
print('You won in', moves,'moves!')
break
Note that function names make good comments. Instead of checkForVictory()
we just put #check for victory
. I recommend you start comments with why, and then with how. How-comments should eventually be removed (you can read the code), and why-comments should stay, but when learning how to program, having the explanation next to the code just helps. It also promotes micro problem-solution flow (in my opinion), which is what you need later if you want to split up code into smaller chunks or problems.
And this loop here...
for i in range(grid):
if i == dy and i == y:
for u in range(grid):
if u == dx:
print('@ ', end='')
elif u == x:
print('x ', end='')
else:
print('# ', end='')
print()
elif i == y:
print('# '*x, end="")
print('x ', end="")
print('# '*((grid-x)-1))
elif i == dy:
print('# '*dx, end="")
print('@ ', end="")
print('# '*((grid-dx)-1))
else:
for i in range(grid):
print('# ', end="")
print()
Is mighty confusing. There is no easily discernible pattern to it. If you had to explain the thought process that went into each step, what would you say? (Teacher, I don't understand, how did you create this?)
Here's mine:
per tile:
print dragon if dragon is on tile
print player if player is on tile
print empty tile if nobody is on tile
Those are the requirements, next up is realizing that if we have a grid, we ought to do it by row and columns:
for each row
for each column
if the dragon is on that tile
print dragon
else if the player is on that tile
print player
else
print empty tile
print new line, to go to next row
And then translate to python (untested)
for i in range(grid)
for u in range(grid)
if i == dragon_y and u == dragon_x:
print('@ ', end='')
elif i == player_y and u == player_x:
print('x ', end='')
else:
print('# ', end='')
print()
Another reason for this is that if you were to get a question like, "how do we add mountains, where the dragon can wander, but the player can't?", you'd be stumped. Or at least I would be, if I had to add mountains into your display code. It's all about clever tricks with multiplying strings. You'd have to alter ALL your cases. Or if there were two dragons, because, you know, hard mode. Again, it would take you a major overhaul.
I'd just make a simple change:
for each row
for each column
if there is a dragon on that tile
print dragon
else if the player is on that tile
print player
else if that tile is a mountain
print mountain
else
print empty tile
print new line, to go to next row
and it supports mountains and multiple dragons!
Possibly the best thing you could do is take another look at your code, and remove the python element from it. Start in English, and convert that to python. I bet that's what the kids will be doing.
Using an approach like this, the code is going to be a lot shorter and easy to understand. Yes, it's slower by doing all the checks all the time. But for these kids, it's probably going to be more important that they understand the code, than that it runs three times as fast. Computers these days are forgiving, and you can always teach them better optimizations later.
Plus, if they were to shy away from programming because the code is too complex, that'd be a darn shame.
And get comfortable with your code before the lesson. It would be best if you could do live editing in the classroom.
As for industry standards...
for i in range(grid):
if i == dy and i == y:
for u in range(grid):
if u == dx:
print('@ ', end='')
elif u == x:
print('x ', end='')
else:
print('# ', end='')
print()
elif i == y:
print('# '*x, end="")
print('x ', end="")
print('# '*((grid-x)-1))
elif i == dy:
print('# '*dx, end="")
print('@ ', end="")
print('# '*((grid-dx)-1))
else:
for i in range(grid):
print('# ', end="")
print()
Extract to printGrid
.
m = input('Which way would you like to move?(N,E,S or W)').lower()
if m == 'n' and y > 0:
y = y-1
elif m == 'e' and x < (grid-1):
x = x+1
elif m == 's' and y < (grid-1):
y = y+1
elif m == 'w' and x >0:
x = x-1
else:
print('Invalid move')
moves = moves + 1
Extract to pickMove
, and use a while loop to make sure that the move counter (moves
) doesn't go up if you make a bad move.
Encapsulate conditionals by putting checks like dy == y and dx == x
into either a function isDragonEatingPlayer
(naming is hard) or just a temporary variable of some sorts.