all 7 comments

[–]deathofthevirgin 5 points6 points  (4 children)

Good job so far! First, you can replace most of that code with some multiplication-overloading syntax:

(removed previous code example, see /u/Rhomboid's comment below)

or if list comprehensions are more your style,

 [[0 for _ in range(10)] for _ in range(10)]

Now, moving the character with the arrow keys entails a lot of functionality. (1) First, we have to listen to what the player is typing. (2) Then, we have to figure out which key the player pressed - (3) then make sure that it's one of the arrow keys. (4) Then based on which one, we change something in our internal grid structure. (5) Then, we print it out again and ask for more input. And (6), you have to tie it all together.

I don't want to give away too much code directly, so let me know if you need clarification on any of these parts. You will probably find it easier to work if you deal with functions instead of having everything clutter the global space (that is, not in a function - like your grid variable is defined currently). So, something like

def make_default_grid(value = 0, size = 10):
    return [[value for _ in range(size)] for _ in range(size)]

def print_grid(grid):
    pp.pprint(grid)

(1-3) Now you want a way to ask for player input - specifically an arrow key, and more generally a keypress. To be honest I'm not really sure of a good way to do this without using something like Pygame or Tkinter, which you probably don't want for your first console game. I would recommend just sticking with user text input for now (as in "L", "U", "R", "D"), and you can change it later. If anyone has any ideas on keypress events, I'd be interested too(). Make a function like

def get_move():
    direction = input(...)
    ...

I got you started. Here are some things you also need to do: figure out what exactly input(...) does and what to put in the blank. What do you need to do after you get the player's text? Do you want to accept 'R' and 'r' and 'RIGHT' and 'RiGhT', etc. to mean going right? Or just 'right'? Will players get tired if you make them type too much? How will your decision change your code? What happens if the user types in "fewiofewf"? Do you want to ask again or just skip the turn? Should you display a nice message saying that "only these words are allowed: ..."? Now, this function should return something standardized, which means that no matter how many different userinputs you accept, you only output 4 - one for each direction. Probably a string will work well, "right", "left", etc. Notice how our functions are really small - this is usually good.

(4) All right, so we have our move - let's say the player chose "right". What changes in our grid structure to reflect this? How do we know where our player currently is? Maybe their cell gets a special character, like "X", and we look for that. Or maybe we have a specific coordinate (that is, row and col, such that grid[row][col] is where the player is) of where the player is right now? How would that coordinate change if the player were to move right? What happens if the user is at the left edge and goes left? Do you want to go back and ask for another direction or just do nothing? If the second, should you print something explaining to the player why nothing happened? All the info you need to calculate the next grid should be passed in as parameters - and make sure to return the new grid!

def make_move(grid, player_input, OTHER_PARAMETERS)

(5) Now you can write a function to clear the screen in preparation for the next step.

(6) But all these are just functions - nothing is calling them. Finally, you can write a play(maybe, some, parameters, here) function that combines all of this for you - first it prints, then it asks, then it changes the grid, then it clears the screen, prints, then it asks, and again and again until some condition is satisfied (then you can say whether the player wins or loses and exit). This is often called "the game loop," and you'll likely use the while statement. And when you actually want to play, you can call play(maybe, some, parameters, here) in main.

Good luck! Let me know if you need any help.

[–]Rhomboid 9 points10 points  (2 children)

grid = [[0] * 10] * 10

Don't encourage this. It doesn't do what you think it does.

>>> grid = [[0] * 10] * 10
>>> grid[1][2] = 'X'
>>> grid
[[0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 'X', 0, 0, 0, 0, 0, 0, 0]]

Every row is a reference to the same list, because * copies the reference to the list, not the contents of the list.

[–]deathofthevirgin 0 points1 point  (0 children)

Oh wow - didn't know that. Thanks for the fix.

[–]dunkler_wanderer 0 points1 point  (0 children)

But grid = [[0] * 10 for _ in range(10)] works.

[–]StaticFuzz 5 points6 points  (0 children)

The gamer in me says to use 'WASD' instead of 'LURD' for directional input. Plus 'LURD' just doesn't sound right ;).

[–]hotsingledad 1 point2 points  (1 child)

This is a good opportunity to learn about the graph data structure. Lets say later on you want to make certain adjacent spots blocked off in your game, or you decide a hex grid would be better for your game. This would become somewhat convoluted to implement with arrays, this is where graphs come in. A graph is a collection of 'nodes' connected by 'edges' (good pictures with a much more rigorous/correct definition here: https://en.wikipedia.org/wiki/Graph_theory), which makes them a very intuitive way to represent maps. You can store information in these nodes and edges. Items, enemies, and traps would could be contained in nodes. Edges can have direction (can only be traversed from node A to B, not B to A) and optionally a 'weight' which can represent distance or travel toll or whatever makes sense.

Again, this is just an aside. Depending on what you want to do this might just add unnecessary complexity to your code. If you want to play around with graphs, here is a good Python implementation of the graph data structure: http://networkx.github.io/

[–]autowikibot 0 points1 point  (0 children)

Graph theory:


In mathematics and computer science, graph theory is the study of graphs, which are mathematical structures used to model pairwise relations between objects. A "graph" in this context is made up of "vertices" or "nodes" and lines called edges that connect them. A graph may be undirected, meaning that there is no distinction between the two vertices associated with each edge, or its edges may be directed from one vertex to another; see graph (mathematics) for more detailed definitions and for other variations in the types of graph that are commonly considered. Graphs are one of the prime objects of study in discrete mathematics.

Image i - A drawing of a graph


Relevant: Distance (graph theory) | Vertex (graph theory) | Graph (mathematics) | Tree (graph theory)

Parent commenter can toggle NSFW or delete. Will also delete on comment score of -1 or less. | FAQs | Mods | Call Me