Skip to content

Instantly share code, notes, and snippets.

@nastysloper
Last active October 22, 2018 22:19
Show Gist options
  • Save nastysloper/7d87f7499607464f24493a900bc834ee to your computer and use it in GitHub Desktop.
Save nastysloper/7d87f7499607464f24493a900bc834ee to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
'''
Python Battleship game.
Learning objectives:
Place multiple ships of multiple lengths, distributed randomly.
How to score hits?
Implement game stats - Print / read to a flat file (json), then use a database
Make it a multi-player game
Score for each player, different board and ships? Websockets to play from a different computer? Login? Sure.
Multiple types of ships ^ * #...
Bugs:
Ships float over one another
How to determine if a ship is sunk? Store coordinates for each ship?
I think Ship needs to be a class.
Maybe Game needs to be a class to track ships, players, etc.
'''
from random import randint
import sys
'''
Set global variables
'''
game_over = False
guess_col = 0
guess_row = 0
'''
Define functions
'''
def print_board(board):
print "\n"
for row in board:
print " ", " ".join(row)
print "\n"
'''
Build the board
'''
board = []
for i in range(1,6):
row = []
for i in range(1,6):
row.append("O")
board.append(row)
'''
Build and place the ships
'''
print "how many ships would you like?"
while True:
num_ships = int(raw_input("Enter an integer between 1 and 3: "))
if num_ships not in range(1,4):
print "That's not valid."
else:
break
ship_types = ["^", "*", "#"]
ships = []
for i in range(num_ships):
'''
Try 3 times to place each ship to avoid collisions
A ship will be 3 units long
Bug fix: place the ship's coordinates in a list, that way we remember where each ship lives,
and if placing a ship fails, retry twice before throwing away the list
'''
print "Ship", i
ship_type = ship_types.pop()
print "Attempting to place ship..."
ship_row = randint(0,4)
ship_col = randint(0,4)
ship = []
ship_bow = []
ship_mid = []
ship_stern = []
if board[ship_row][ship_col] == "O":
board[ship_row][ship_col] = ship_type
else:
pass
''' Ship will be aligned on either x or y axis'''
alignment = randint(1,2)
# 1 means north-south
# 2 means east-west
if alignment == 1:
# ships are three units long
for j in range(3):
'''check for edge of board'''
if ship_row + j > 4:
print "row is", ship_row + 1
print "You're off the board"
for k in range(2):
if (board[ship_row - k][ship_col] == ship_type):
pass
else:
board[ship_row - k][ship_col] = ship_type
else:
board[ship_row + j][ship_col] = ship_type
else:
# ships are three units long
for j in range(3):
if ship_col + j > 4:
print "col is", ship_col + 1
print "You're off the board"
for k in range(2):
if (board[ship_row][ship_col - k] == ship_type):
pass
else:
board[ship_row][ship_col - k] = ship_type
else:
board[ship_row][ship_col + j] = ship_type
print "Here are your ships:"
print ship_row, " ", ship_col
'''
Start the game
'''
print "\n"
print "Welcome to Battleship!"
while not game_over:
print_board(board)
print "Enter the coordinates you want to fire upon:"
guess_col = int(raw_input("Enter an integer from 1 to 5 to specify the column: "))
while guess_col not in range(1,6):
print "That's not a valid number."
guess_row = int(raw_input("Enter an integer from 1 to 5 to specify the row: "))
while guess_row not in range(1,6):
print "That's not a valid number."
'''
Programmers count from 0
'''
guess_col -= 1
guess_row -= 1
if board[guess_row][guess_col] != "O":
board[guess_row][guess_col] = "X"
print_board(board)
print " You win!", "\n"
game_over = True
else:
board[guess_row][guess_col] = "X"
print_board(board)
# Don't forget to check on intialization for a card length
# of exactly 16 digits
class CreditCard
attr_reader :numbered, :num
def initialize num
@num = num
@numbered = num.to_s.split('')
throw ArgumentError if numbered.length > 16
throw ArgumentError if numbered.length < 16
end
def check_card
ints = numbered.map { | element | element.to_i }
doubleds = []
ints.each_with_index do | element, index |
if index % 2 == 0
temp = element * 2
temp = temp.to_s.split('')
doubleds << temp
else
doubleds << element
end
end
print doubleds.flatten!
print "\n"
doubleds.map! { | element | element.to_i }
print doubleds
print "\n"
sum = doubleds.reduce(:+)
p sum
print "\n"
if sum % 10 == 0
puts "Valid!"
return true
else
puts "No gud!"
return false
end
end
end
# my_card = CreditCard.new(1111_1111_1111_1112)
# my_card.check_card
import com.fasterxml.jackson.annotation.JsonCreator;
public class Dog {
public String name;
public int age;
public String breed;
@JsonCreator
public Dog() {
this.breed = "mutt";
this.name = "doggy";
this.age = 5;
}
public Dog(String name, String breed, int age) {
this.age = age;
this.name = name;
this.breed = breed;
}
}
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("allo")
public class Hello {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "allo, there";
}
@POST
@Produces(MediaType.TEXT_PLAIN)
public String dog() {
return "You're getting a doge, dude!";
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("dog")
public Dog createDog() {
return new Dog();
}
}
@nastysloper
Copy link
Author

The Java Dog Web app is the example of code that made me smile. It has dogs, so of course it's fun!
There's no thorny business logic here. The complexity involved getting a Java web
app to run and respond to requests which is more complex than using something like
Express. You have to create a web archive file, then move that into a special directory
for the Catalina server to recognize it. Just getting the imports to work was work.
Once it ran I added the Jackson library to serialize the dog object into JSON.

The Python battleship game is an example with more complex business logic. I've got some good TODO comments and suggestions for
new features. I feel like there's too much going on all in one place, however. It feels like I was just trying to get it working before
I started refactoring.

I'm not super excited about my Ruby credit card validation code.
The biggest issue I have with this is poor documentation. How is the card being validated?
Organization could also be better. Perhaps the card check routine could call different methods with semantically-
meaningful names (making it clearer what's happening) to execute the various card checks (length, checksum, last digit, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment