3
\$\begingroup\$

Before starting I would like to say that I just made this program after studying python for 5 hours for the first time so I am totally new to this programming language.

This program tries to create 4X4 board denoting it with 0 everywhere. Now to deploy treasure, it randomly selects 9 position and deploy them on the board by denoting it with '@'. Then tries to detect neighboring treasure which are there around vacant lands and counts them and then show them on those vacant lands area. It is just like Minesweeper game.

Since I am new to this python language so I would like to know that what changes do I have to make so that it will look like a Python program and what else I can do to make it work much better.

from random import randint

print "Welcome to Treasure Hunt \n"

q="@"     #For checking the treasure
board = []  #Board

for x in range(0,4):
    board.append(["0"] * 4)   # It creates 4x4 Board with 0 everywhere

treasure = 9
while treasure:                # Randomly spread treasure
 r = randint(0, len(board)-1)
 c = randint(0, len(board[0])-1)
 if board[r][c] != "@":
        board[r][c]="@"
        treasure -= 1

print "-------------------------------"
print "\n Treasures are here "
print "\n-------------------------------\n"
for row in board:
    print "     ".join(row)                  # Give output of board
    print "\n"


def hunt(a,b):              #Hunt function searches for treasure around the given land
    first = a-1
    second = b-1
    third = a+1
    fourth = b+1
    if(first < 0):
        first = first + 1;
    if(second < 0):
        second = second + 1;
    if(third == 4):
        third = third - 1;
    if(fourth == 4):
        fourth = fourth -1;

    h=0
    for i in range(first,third + 1):
        for j in range(second,fourth + 1):
            if(q==board[i][j]):
                h=h+1;
                board[a][b] = h

for k in range(len(board)):
    for l in range(len(row)):
        if(q!=board[k][l]):
            hunt(k,l)

for row in board:
    print "   ".join(map(str,row))
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Review! Good job on your first question, I hope you get some great answers! \$\endgroup\$
    – Phrancis
    Mar 28, 2016 at 14:37

1 Answer 1

1
\$\begingroup\$

Styling

The Python style guide, PEP 8, has some good things to say. I have found very few things in it of which I do not approve. Certainly there are some that I don't agree with, but for the most part it makes your code easier to understand if you follow its guidelines.

These two rules from PEP 8 you aren't following:

Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and, or, not).

and

Use 4 spaces per indentation level.

You break that last in only one place: in your while treasure: loop. It might be just a typo, but even typos sometimes break your program.

Using first = a-1 is not against PEP 8, but I think it looks better to use first = a - 1.

Naming

You have many variables with names that are almost or completely meaningless. For example, r = randint(0, len(board)-1). If I look down a couple lines, I can gather that r stands for row; but what's wrong with naming it row in the first place? Each line of code should be semi-readable without any other lines as context. You use just about half of the letters in the alphabet as variable names, but you have only about five names that are actually descriptive. You use first, second, third, and fourth; but what are they really? Are they perhaps row_start, row_end, column_start, and column_end?

Logic

I'm not sure; maybe this should go under Styling, but I think you should use parentheses in your print statements. Python3 has print as a function so they are required. They are allowed in Python2, so I usually use them. It can trip you up sometimes if you do print("Your score was", 45), say, because it would print ('Your score was', 45) instead of Your score was 45. Since you aren't using comma-separated values in your print calls, everything should look exactly the same. You may want to put from __future__ import print_function at the top so that if you add something later that uses comma-separated values, it will still print out all right.

q = "@"

Why do you use "@"? I'm guessing that you use it because "@" is the default space-filler. You use "@" in many places, so what if you decided to use "%" instead? That would require a lot of modification. What you have right now is called hard-coded values. Instead of that, define a constant at the beginning of the file that defines which character it is, and use that constant instead of saying "@" explicitly.

board = []
for x in range(0, 4):
    board.append(["0"] * 4)

range() by default starts at 0, so you could use for x in range(4): instead. Since you aren't using x, the standard name is _. The easy way to define board would be to use a list comprehension:

board = [["0"] * 4 for _ in range(4)]
r = randint(0, len(board)-1)

There is another function in the random module that is closer to what you want: randrange(). Of course, you would need to change from random import randint to from random import randrange, but the code would be:

row = randrange(len(board))
column = randrange(len(board[row]))
first = a-1
second = b-1
third = a+1
fourth = b+1
if(first < 0):
    first = first + 1;
if(second < 0):
    second = second + 1;
if(third == 4):
    third = third - 1;
if(fourth == 4):
    fourth = fourth -1;

For one thing, those semicolons are redundant. You could also shorten your code using max() and min():

first = max([a - 1, 0])
second = max([b - 1, 0])
third = min([a + 1, 4])
fourth = min([b + 1, 4])

But why do you use 4? What's special about it? Is that another hard-coded value?

All together, you have done very well for studying only five hours. I haven't seen you on StackOverflow, so you appear to be quite good at researching what you need. I believe that your main problem is that you are too focused on the project at hand. You haven't made it easy to change little details about the program, and you haven't made it easy for other people to understand your code. PEP 8 mentions that code is read much more often than it is written. If you came back in five years, would you be able to explain the program to someone else?

\$\endgroup\$
1
  • \$\begingroup\$ I totally agree for what you just said. Well it was really a great explanation just what I was expecting. If it comes to logic then I totally agree that its really poor. Why poor because I could have done it much better but for the sake of this project (just to make it work) I have added so many max and min variables. I might have added fourth one for testing I am not sure but overall I made up one C++ program logic in mind and then i implemented it in python. Since python looping style is way different from C++ that's why it is complicated. \$\endgroup\$
    – Shashank
    Mar 28, 2016 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.