### [Reduce global variables][1]
The `game_type` function can return the ship row and column, there is no need to modify them as global variables, my suggestion is easy to implement:
def game_type(game_input):
if game_input == 1:
ship_row = random_row(board)
ship_col = random_col(board)
elif game_input == 2:
ship_row = int(raw_input("Choose a Row to place your battleship:"))
ship_col = int(raw_input("Choose a Column to place your battleship:"))
else:
print "That is not a valid input. Please try again"
return game_type(int(raw_input("To play against the computer press 1, to play against a friend press 2: \n")))
return ship_row, ship_col
ship_row, ship_col = game_type(int(raw_input(
"To play against the computer press 1, to play against a friend press 2: \n")))
Also, `columns` is only ever used inside `print_board` so I would define it as a default parameter, to make it clear that the rest of the program does not need it:
def print_board(board, columns = [" 0", "1", "2", "3", "4"]):
print "\t\t", " ".join(columns)
for row_num, row in enumerate(board):
print "\t\t", row_num, " ".join(row)
### First define, then "do stuff"
Organization is a nice property of code. Now you mix function definitions and code that "does things" (namely code that interacts with the user).
I would define at first all of the functions, and then run them.
**Use `enumerate`**
99% of the times manually incrementing a counter is not needed in Python:
def print_board(board, columns = [" 0", "1", "2", "3", "4"]):
print "\t\t", " ".join(columns)
for row_num, row in enumerate(board):
print "\t\t", row_num, " ".join(row)
Using built-ins is usually simpler than writing your own.
**Avoid do-nothing lines**
In Python the line:
value
Where value may be anything, does nothing. In your code the line
turn
Does nothing at all, remove it to simplify the code.
**List comprehension + `_`**
A list comprehension is preferred over `append` in simple cases, `_` signifies that you are not interested in the value.
board = [["-"] * 5 for _ in range(5)]
**Remove unused definitions**
`row_num` is defined but never used, so delete the line:
row_num = ["0", "1", "2", "3", "4"]
**Use the `range` that fits your needs best**
>>> help(range)
Help on class range in module builtins:
class range(object)
| range(stop) -> range object
| range(start, stop[, step]) -> range object
|
| Return a sequence of numbers from start to stop by step.
...
Using the second version of `range` will avoid incrementing afterwards:
for turn in range(1, 5):
print "Turn", turn
I also find it more obvious this way that turns are 1-indexed.
[1]: http://c2.com/cgi/wiki?GlobalVariablesAreBad