how would I go about making this code "cleaner"? Right now it's a pain to look at and try to understand.

from msvcrt import getwch, kbhit
from os import system
from time import sleep
from random import randint

def check_type(num, type):
# Check if int, if not return 0
if type == int:
try:
float(num)
except:
print(" Error: Not number.")
print()
return 0
else:
# Check if has decimal
try:
int(num)
except:
print(" Error: Number can't have a decimal.")
print()
return 0
# Check if float
elif type == float:
try:
float(num)
except:
print(" Error: Not number.")
print()
return 0
# Check if string
elif type == str:
try:
str(num)
except:
print(" Error: Not string.")
print()
return 0
return type(num)

exit = 0
while exit == 0:
print("Game settings")

""" Board """
board = []

# Board size input
board_size = check_type(input(" Board size: "), int)
if board_size == 0:
continue

aspect_ratio = 16 / 9
for num in range(board_size):
board.append(["."] * round(board_size * (aspect_ratio)))

""" Variables """
# Defaults x and y to middle of the board
x = round((board_size * (aspect_ratio)) / 2) - 1
y = round(board_size / 2)

# Defaults to moving right
directionx = 1
directiony = 0

key_press = 0
count = -1
apple_count = 0
x2 = []
y2 = []
applex = 0
appley = 0
apple_count_count = 0

# Speed input
while 1:
speed = check_type(input(" Speed (lower = faster): "), float)
if speed == 0:
continue
else:
break

speed_increment = 0
x2.append(x)
y2.append(y)

""" Main """
while board[y][x] != "x":
# Loops board while no key presses
while kbhit() == 0:
x += directionx
y += directiony
# Border overflow check
if x >= round(board_size * (aspect_ratio)) and directionx == 1:
x = 0
elif x < 0 and directionx == -1:
x = round(board_size * (aspect_ratio)) - 1
if y >= board_size and directiony == 1:
y = 0
elif y < 0 and directiony == -1:
y = board_size - 1
# Checks to see if crash
if board[y][x] == "x":
while 1:
print()
print("You have crashed!")
# User input
while 1:
exit = check_type(input("Restart? (yes/no): "), str)
if exit == 0:
continue
else:
break
if exit.lower() == "yes":
exit = 0
break
elif exit.lower() == "no":
exit = 1
break
system("cls")
break
# If eat apple
elif board[y][x] == "o":
apple_count += 1
apple_count_count = 0
board[y][x] = "X"
x2.append(x)
y2.append(y)
# Makes body small x
board[y2[count + 1]][x2[count + 1]] = "x"
# Tail eater
if count - apple_count >= 0:
board[y2[count - apple_count]][x2[count - apple_count]] = "."
count += 1
# Only allows one apple at a time
if apple_count_count <= 10:
# Makes sure apple doesnt spawn on anything
while apple_count_count == 10:
applex = randint(0, round(board_size * (aspect_ratio)) - 1)
appley = randint(0, board_size - 1)
if board[appley][applex] != ".":
continue
board[appley][applex] = "o"
break
apple_count_count += 1
# Clears previous board then prints updated one
system("cls")
for row in board:
print(" ".join(row))
# Prints extra info
print("Speedup: +%d%%  Apple count: %d" % (round(((speed - (speed - speed_increment)) / speed) * 100), apple_count))
# Delay the loop
sleep(round(speed - speed_increment, 2))
if speed - speed_increment >= speed / 2:
speed_increment += speed / 1000
key_press = 0
# Game logic
else:
key = getwch()
if key == "w" and directiony != 1 and key_press == 0:
directionx = 0
directiony = -1
key_press = 1
elif key == "a" and directionx != 1 and key_press == 0:
directionx = -1
directiony = 0
key_press = 1
elif key == "s" and directiony != -1 and key_press == 0:
directionx = 0
directiony = 1
key_press = 1
elif key == "d" and directionx != -1 and key_press == 0:
directionx = 1
directiony = 0
key_press = 1


I was thinking about turning some while loops into functions but I'm not sure if that would make the game run "slower". I'm planning on getting into website back-end development so knowing how to write code with good performance would be handy.

Also, how should I go about commenting? Creating a newline at the end of every section I comment doesn't seem efficient at all. Is there some sort of guideline about commenting?

Any help would be greatly appreciated!

Functions

You can greatly improve your use of functions. For example, you could wrap the game logic into a function called game_logic() and call that. The same goes for your 'main' loop, which can be wrapped in game_loop().

Improving check_type()

• Using a plain except clause is not a good idea. Especially for longer and more complicated projects, this might inadvertently catch unrelated exceptions (and even things like keyboard interrupts). To avoid this, use except ValueError.

• Returning 0 can confuse people because it looks similar to the exit code (0). Consider returning False.

Simplifying game logic

To shorten the length of the main game logic, you could put the second part in a boolean variable:

conditional = not directory and not key_press
if key in ("w", "a", "s", "d"):
key_press = True

if key == "w" and conditional:
directionx, directiony = 0, -1
elif key == "a" and conditional:
directionx, directiony = -1, 0
elif key == "s" and conditional:
directionx, directiony = 0, 1
elif key == "d" and conditional:
directionx, directiony = 1, 0


Don't use os.system()

If you need to clear the screen, you can do something like print("\n" * y) where y is the vertical height of your terminal. You could also use a carriage return. This has the added advantage of being cross-platform, as opposed to system calls.

Questionable code

Here's some things I thought were quite unusual:

• Why are you starting print() calls with a space? And why are you doing that inconsistently?

• Why are you using docstrings where they are not needed?

• You have some redundant comments, for example # Speed input to explain the use of a variable called speed_input.

• You are using 1 and 0 a lot for boolean logic, which I find quite confusing. Where possible, it would be better to use bool, i.e. True, False.

• It is not needed to check the type of exit. input() will always return a string.

Bugs

• If there's an error converting board_size to integer, the board size will remain 0. Set a default size to avoid this.

• Trying to turn a float into an integer will never raise an exception, so using that to check for decimal numbers is useless.

• Hey, thanks for all of your suggestions! It really opened my mind about the things I was doing wrong, although I do have a few questions. Firstly, where would I find a list of all the exception handlers? Seems like an important thing to know. Also, why shouldn't I be using os.system("cls")? And what is a main() guard? Commented Jun 25, 2017 at 20:49
• Briefly addressing your questions: 1 You can take a look the Python docs, which has all the built-in exceptions nicely listed and explained. 2 Using os.system() is dangerous because it opens gates for attackers (shell hijacking). 3 A name guard is an if-statement that makes sure code such as unit tests or code 'logic' only work if the file is run as 'main' program. That way, if you import it into another file as module, the logic won't run. See also Commented Jun 26, 2017 at 6:24