Skip to content
This repository was archived by the owner on Nov 18, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions Python/Player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import math
import random


class Player():
def __init__(self, player):
self.player = player

def get_move(self, game):
pass


class Human(Player):
def __init__(self, player):
super().__init__(player)

def get_move(self, game):
valid_square = False
val = None
while not valid_square:
square = input(self.player + ' turn. Please introduce a move (1-9): ')
try:
val = int(square) - 1
if val not in game.remaining_moves():
raise ValueError
valid_square = True
except ValueError:
print('Invalid square. Try again.')
return val


class RandomComputer(Player):
def __init__(self, player):
super().__init__(player)

def get_move(self, game):
square = random.choice(game.remaining_moves())
return square


class SmartComputer(Player):
def __init__(self, player):
super().__init__(player)

def get_move(self, game):
if len(game.remaining_moves()) == 9:
square = random.choice(game.remaining_moves())
else:
square = self.minimax(game, self.player)['position']
return square

def minimax(self, state, player):
max_player = self.player
min_player = '0' if player == 'X' else 'X'

# checking if the previous move is winner
if state.actual_winner == min_player:
return {'position': None,
'score': 1 * (state.number_null_squares() + 1) if min_player == max_player
else -1 * (state.number_null_squares() + 1)}
elif not state.null_squares():
return {'position': None, 'score': 0}

if player == max_player:
best = {'position': None, 'score': -math.inf}
else:
best = {'position': None, 'score': math.inf}

for possible_move in state.remaining_moves():
state.make_a_move(possible_move, player)
sim_score = self.minimax(state, min_player)

# undo move
state.board[possible_move] = ' '
state.actual_winner = None
sim_score['position'] = possible_move

if player == max_player:
if sim_score['score'] > best['score']:
best = sim_score
else:
if sim_score['score'] < best['score']:
best = sim_score
return best
104 changes: 104 additions & 0 deletions Python/TicTacToe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import math
import time
from Player import SmartComputer, RandomComputer, Human


class TicTacToe():
def __init__(self):
self.board = self.create_board()
self.actual_winner = None

@staticmethod
def create_board():
return [' ' for _ in range(9)]

def board_show(self):
for cell in [self.board[i*3:(i+1)*3] for i in range(3)]:
print('| ' + ' | '.join(cell) + ' |')

@staticmethod
def show_board_numbers():
number_from_board = [[str(i + 1) for i in range(j*3, (j+1)*3)] for j in range(3)]
for cell in number_from_board:
print('| ' + ' | '.join(cell) + ' |')

def make_a_move(self, square, player):
if self.board[square] == ' ':
self.board[square] = player
if self.winner_rules(square, player):
self.actual_winner = player
return True
return False

def winner_rules(self, square, player):
# Checking the row
row_index = math.floor(square / 3)
row = self.board[row_index*3:(row_index+1)*3]
if all([l == player for l in row]):
return True

# Checking the column
col_index = square % 3
column = [self.board[col_index+i*3] for i in range(3)]
if all([l == player for l in column]):
return True

# Checking for diagonal
if square % 2 == 0:
principal_diagonal = [self.board[i] for i in [0, 4, 8]]
if all([l == player for l in principal_diagonal]):
return True

secondary_diagonal = [self.board[i] for i in [2, 4, 6]]
if all([l == player for l in secondary_diagonal]):
return True

return False

def null_squares(self):
return ' ' in self.board

def number_null_squares(self):
return self.board.count(' ')

def remaining_moves(self):
return [p for p, i in enumerate(self.board) if i == ' ']


def play(game, x_player, o_player, show_game = True):
if show_game:
game.show_board_numbers()

player = 'X'
while game.null_squares():
if player == '0':
square = o_player.get_move(game)
else:
square = x_player.get_move(game)
if game.make_a_move(square, player):
if show_game:
print(f'{player} makes a move to square {square}')
game.board_show()
print(' ')

if game.actual_winner:
if show_game:
print(f'{player} wins!')
return player
player = '0' if player == 'X' else 'X'

time.sleep(.8)

if show_game:
print('Tie!')


if __name__ == '__main__':
#x_player = RandomComputer('0')
x_player = SmartComputer('0')
o_player = Human('X')
t = TicTacToe()
play(t, o_player, x_player, True)



60 changes: 60 additions & 0 deletions Python/reddit_scraper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import requests
import csv
import time
from bs4 import BeautifulSoup


class HaikuScraper:
"""
This scraper is designed with the purpose of scraping Haikus (Japanese poems) from Reddit.
"""
def __init__(self, url: str, headers: dict):
self.url = url
self.headers = headers

def make_request(self):
time.sleep(3)
page = requests.get(self.url, headers=self.headers)
soup = BeautifulSoup(page.text, 'html.parser')
return soup

def get_next_page(self, soup: BeautifulSoup):
time.sleep(3)
next_button = soup.find('span', class_='next-button')
next_page_link = next_button.find("a").attrs['href']
return next_page_link

def get_haikus(self, soup: BeautifulSoup):
haikus = [str(title.text) for title in soup.find_all("a", class_="title may-blank ")]
return haikus

def write_haikus_to_csv(self, haikus: list):
with open('scraped_haikus_v2.txt', 'a') as f:
writer = csv.writer(f)
for haiku in haikus:
writer.writerow([haiku])
f.close()



url = "https://old.reddit.com/r/haiku/"
# Headers to mimic a browser visit
headers = {'User-Agent': 'Mozilla/5.0'}

scraper = HaikuScraper(url, headers)
soup = scraper.make_request()

haikus = scraper.get_haikus(soup)
scraper.write_haikus_to_csv(haikus)

counter = 1

while (counter <= 2500):
time.sleep(2)
link = scraper.get_next_page(soup)
print(f"Page {counter + 1}. Link {link}.")
scraper = HaikuScraper(link, headers)
soup = scraper.make_request()
haikus = scraper.get_haikus(soup)
scraper.write_haikus_to_csv(haikus)
counter += 1