# Python Game Tic Tac Toe

I implemented this very simple game for my book Python 3 Exercises for Beginners.

Source Code available here:

https://gitlab.com/carles.mateo/python-classes/-/blob/main/2021-09-10/game_tic-tac-toe.py

``````
class TicTacToe:

def __init__(self):
self.a_a_s_map = []
self.generate_map()

def generate_map(self):
self.a_a_s_map = []

for i_y in range(3):
a_s_pos_x = [" ", " ", " "]
self.a_a_s_map.append(a_s_pos_x)

def get_map(self):
s_map = ""

s_map = s_map + "    1   2   3\n"
s_map = s_map + "  -------------\n"
for i_y in range(3):
s_map = s_map + str(i_y + 1) + " |"
for s_char in self.a_a_s_map[i_y]:
s_map = s_map + " " + s_char + " |"
s_map = s_map + "\n"
s_map = s_map + "  -------------\n"

return s_map

def validate_move(self, s_char, i_x, i_y):
"""
Validates the movement and updates the map
:param s_char:
:param i_x:
:param i_y:
:return: bool
"""
i_x = i_x - 1
i_y = i_y - 1

if self.a_a_s_map[i_y][i_x] == " ":
self.a_a_s_map[i_y][i_x] = s_char
return True

return False

def check_win(self):
for s_char in ["O", "X"]:

# check horizontal
for i_y in range(3):
i_horizontal_match = 0
for i_x in range(3):
if self.a_a_s_map[i_y][i_x] == s_char:
i_horizontal_match = i_horizontal_match + 1
if i_horizontal_match == 3:
return True

# Check vertical
for i_x in range(3):
i_vertical_match = 0
for i_y in range(3):
if self.a_a_s_map[i_y][i_x] == s_char:
i_vertical_match = i_vertical_match + 1
if i_vertical_match == 3:
return True

# Check diagonal
if self.a_a_s_map[1][1] == s_char:
if self.a_a_s_map[0][0] == s_char and self.a_a_s_map[2][2] == s_char:
return True
if self.a_a_s_map[0][2] == s_char and self.a_a_s_map[2][0] == s_char:
return True

return False

def check_stale(self):
for i_y in range(3):
for i_x in range(3):
if self.a_a_s_map[i_y][i_x] == " ":
# Is not full
return False

# We checked all and all were full
return True

def get_from_keyboard(s_question, i_min, i_max):
i_number = 0
while True:
try:
except:
continue

if i_number < i_min or i_number > i_max:
print("Invalid value. Values should be between", i_min, "and", i_max)
continue

# Validations are Ok
break

return i_number

if __name__ == "__main__":
o_tictactoe = TicTacToe()

while True:

s_map = o_tictactoe.get_map()
print(s_map)

while True:
i_x = get_from_keyboard("Your move O for x: ", i_min=1, i_max=3)
i_y = get_from_keyboard("Your move O for y: ", i_min=1, i_max=3)

b_valid_move = o_tictactoe.validate_move("O", i_x, i_y)
if b_valid_move is False:
print("Invalid move")
continue

break

s_map = o_tictactoe.get_map()
print(s_map)
b_check_win = o_tictactoe.check_win()
if b_check_win is True:
print("Player O wins!")
exit(0)

b_stale = o_tictactoe.check_stale()
if b_stale is True:
print("Nobody wins in war")
exit(0)

while True:
i_x = get_from_keyboard("Your move X for x: ", i_min=1, i_max=3)
i_y = get_from_keyboard("Your move X for y: ", i_min=1, i_max=3)

b_valid_move = o_tictactoe.validate_move("X", i_x, i_y)
if b_valid_move is False:
print("Invalid move")
continue

break

s_map = o_tictactoe.get_map()
print(s_map)
b_check_win = o_tictactoe.check_win()
if b_check_win is True:
print("Player X wins!")
exit(0)
``````

# News from the blog 2021-09-07

• Blocking Ip addresses in the firewall

I’ve been blocking entire ranges from Cloud Providers, as some of their Ip’s were being used to try to hack/abuse the blog.

After some time blocking individual Ip’s, I opted for being some more effective and blocking /24 (the class C for the offending Ip).

If you work for a CSP and you can’t see my blog from your range, this is the reason.

• I have updated my two Python books.

For Python 3 simple exercises for beginners I’ve added this new content:

v.0.29 and v.0.28 Python 3 Simple Exercises for Beginners
Added a new section Games, with a first game “Guess my number”

Provided a solution for the recipe Exercise 3: Create a function that will ask a user for a number from Keyboard input, and return the result, only when the value is between the accepted ranges.

Added two new questions to the Quiz section.

Fixed a docstring in Recipes Exercise 4, referring to a String return value which it was an Integer.

Added a new exercise for converting bytes to kilobytes with two decimal positions.

Added a new exercise / recipe to SSH to a Server with Username and Password and execute a command, using the Paramiko library.

For Python 3 Combat Guide I have added this new content:

v.1.02 Python 3 Combat Guide

Added a new exercise / recipe to SSH to a Server with Username and Password and execute a command using Paramiko library. I added two examples executing commands uptime and df -h /

Show an alternative way to run Flask apps.

As long as covid is active I plan to keep the minimum price of each of my books at the minimum accepted by LeanPub which is USD \$5.

I also enable bundles and enable LeanPub to make punctual discounts to make them even more affordable to humble pockets.

• I’m going to teach an initiation to programming class, a live Zoom session of 1 hour, plus 15 minutes for questions, for Free. It will be a very basic starting class for absolute beginners.

It will be performed at a time around 19:00 Irish time, wich is 11:00 AM in Irivine, CA time, to maximize the opportunities for people to assist.

If you would like to join, write me an email:

There are not many spots available, but if there is no room for you this time I may contact you for the next time.

This version adds class StringUtils, and a set of methods to perform different useful tasks with Strings, like converting a number to the biggest unit with sense, like a large number of bytes to PB, a smaller one to TB, or GB, MB, KB, justifying strings to the right or to the left, and cap the number of chars to a specified one, etc…

I have many libraries that I’ve been building across the years, and I’m liberating them as Open Source, as soon as I have time to make sure that are compatible with Python 3.5 or superior (and with Python 2.6 when possible), and I have time to add a decent Unit Testing Code Coverage.

I try to release libraries that have no other dependencies. After that I’ll start releasing my libs that have dependencies, like to work with MySQL, SQLite, web scrapping, etc…

# Video: Beginners Python: teaching to work with for, range, lists, dicts

I recorded this class where some university colleagues and few of my students joined me.

It is recorded at Full HD. Increase Youtube’s quality to make sure the video is smoothly displayed.

You can download the source code from a previous class and this one in Gitlab:

https://gitlab.com/carles.mateo/python-classes