summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTinWoodman92 <chrhodgden@gmail.com>2023-12-16 19:06:36 -0600
committerTinWoodman92 <chrhodgden@gmail.com>2023-12-16 19:06:36 -0600
commitc07fa79f178e27ef16aeda15634555c60b6b695e (patch)
tree64523089937d929625d980785cd99bf2ad8ab047
parentad8730894e0c43860299631dedadf4e027b814f3 (diff)
completed tic tact toe blog.
-rw-r--r--index.html2
-rw-r--r--projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html36
-rw-r--r--projects_blog/presentation_code/tictactoe.md175
-rw-r--r--style.css7
4 files changed, 32 insertions, 188 deletions
diff --git a/index.html b/index.html
index 9d756ee..a3c0a37 100644
--- a/index.html
+++ b/index.html
@@ -27,7 +27,7 @@
<ul>
Personal Projects
<li class="nnetwork"><a href="projects_blog/NNetwork.html">NNetwork</a></li>
- <!-- <li class="tic-tac-toe"><a href="projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html">Tic Tac Toe Machine Learning Lab Kit</a></li> -->
+ <li class="tic-tac-toe"><a href="projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html">Tic Tac Toe Machine Learning Lab Kit</a></li>
</ul>
<nav class="nav-footer">
diff --git a/projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html b/projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html
index 7780765..d2b8145 100644
--- a/projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html
+++ b/projects_blog/Tic-Tac-Toe-ML-Lab-Kit.html
@@ -22,6 +22,7 @@
<hr>
<a href="#background">Background</a>
| <a href="#the-project">The Project</a>
+ | <a href="#what-i-learned">What I Learned</a>
| <a href="#next-steps">Next Steps</a>
<hr>
</nav>
@@ -29,36 +30,47 @@
<a href="https://github.com/chrhodgden/Tic-Tac-Toe-ML-Lab-Kit" target="_blank">GitHub Repository</a>
<h2 id="background">Background</h2>
<p>
- As I was learning python, I made a very simple inteactive tic tac toe game.
+ As I was learning python, I made a very simple interactive tic tac toe game.
I kept polishing it instead of progressing through the tutorial I was in.
In pushing myself to add and debug features I found that I got to a point where I could teach myself by referencing Python's own documentation.
</p>
- <a href="./presentation_code/tictactoe.md" target="_blank">Simple version</a>
- <p>
- This version will work on all platformas that run Python.
- </p>
+ <a href="./presentation_code/tictactoe.py" target="_blank">Simple version</a>
<p>
+ This version will work on all platforms that run Python.
When I got this version complete, I continued with other tutorials to learn about object oriented programming and other Python libraries.
</p>
<h2 id="the-project">The Project</h2>
<p>
- This was a simple and fun project for me to learn python.
- Not all the menu items have been set up and will crash if they are selected.
- The keyboard interface only works with Microsoft Windows OS.
+ I followed most of the next steps on my original version.
+ As a Data Analyst, I wanted to build something that could generate records so I could work with the data.
+ My idea was to build algorithms that could work with historical data that could improve their performance.
+ The first version of data storage was in csv files.
+ Once that was established and I built the algorithms for them to learn,
+ I learned about SQLite databases and migrated the data storage system to use that.
+ Working with SQL was very familiar and fun to me.
</p>
<p>
- It does not apply proper machine learning techniques.
- The "machine learning" is aggregating in raw SQL for each occurance.
- They do infact improve and figure out how to play.
+ This program does not apply proper machine learning techniques.
+ The "machine learning" is aggregating in raw SQL for each occurrence.
+ They do in fact improve and figure out how to play.
+ I had not looked into what real machine learning was until later.
</p>
+ <h2 id="what-i-learned">What I Learned</h2>
+ <ul class="projects-blog">In adding features to this project, I learned:
+ <li>Applications of Object Oriented Programming</li>
+ <li>SQLite and integration with Python</li>
+ <li>Keyboard interface on Windows</li>
+ <li>ANSI Escape characters and displaying color on the Command Line Interface</li>
+ </ul>
+
<h2 id="next-steps">Next Steps</h2>
<p>
Next steps for this project will be to integrate proper machine learning into the the AI profiles.
Then add the rest of the menu elements.
</p>
<p>
- I may decide to do this in JavaScript and HTML with the Math.js or TensorFlow libraries.
+ As charming as the CLI is, I may decide to do this in JavaScript and HTML with the Math.js or TensorFlow libraries.
The potential for this project is educational.
It would be nice to share easily and be more interactive.
</p>
diff --git a/projects_blog/presentation_code/tictactoe.md b/projects_blog/presentation_code/tictactoe.md
deleted file mode 100644
index dab8c4f..0000000
--- a/projects_blog/presentation_code/tictactoe.md
+++ /dev/null
@@ -1,175 +0,0 @@
-```python
-#Next Steps:
-# Build & export move log for games
-# Build a board timeline variable/class - Export this?
-# Build an analysys board class for bots to use thinking through the next commands.
-# Look into usin scikit-learn to create a decistion tree model, then have a bot level that loads and uses the model. - See if you could have it programmed itself playing against the other bot levels. Probably need an X model & O model.
-# Probably need to translate some of the variables as classes -- THIS WILL BE GOOD FOR EDUCATION -- I NEED TO PRACTICE OBJECT-ORIENTED PROGRAMMING AT LEAST ONCE YOU'D THINK.
-# Probably should export the bot functionality to a separate module
-
-
-import random
-
-def prt_brd(brd):
- print(f"""
-3 {brd[0][2]}|{brd[1][2]}|{brd[2][2]}
-2 {brd[0][1]}|{brd[1][1]}|{brd[2][1]}
-1 {brd[0][0]}|{brd[1][0]}|{brd[2][0]}
- a b c
-""")
-
-def rnd(i = 1): return random.randint(0,i)
-
-def bot_cmd(lvl, trn, brd):
- if lvl >= 1:
- #check for potential victory
- #check files and ranks
- for r in range(0,3):
- if brd[r].count(trn) == 2 and brd[r].count(' ') == 1: return file_name[r]+rank_name[brd[r].index(' ')]
- if (brd[0][r]+brd[1][r]+brd[2][r]).count(trn) == 2 and (brd[0][r]+brd[1][r]+brd[2][r]).count(' ') == 1: return file_name[(brd[0][r]+brd[1][r]+brd[2][r]).index(' ')]+rank_name[r]
-
- #check diagonals
- if (brd[0][0]+brd[1][1]+brd[2][2]).count(trn) == 2 and (brd[0][0]+brd[1][1]+brd[2][2]).count(' ') == 1: return file_name[(brd[0][0]+brd[1][1]+brd[2][2]).index(' ')]+rank_name[(brd[0][0]+brd[1][1]+brd[2][2]).index(' ')]
- if (brd[0][2]+brd[1][1]+brd[2][0]).count(trn) == 2 and (brd[0][2]+brd[1][1]+brd[2][0]).count(' ') == 1: return file_name[(brd[0][2]+brd[1][1]+brd[2][0]).index(' ')]+rank_name[(brd[2][0]+brd[1][1]+brd[0][2]).index(' ')]
-
- if lvl >= 2:
- alt_trn = plr_trn[trn == 'X']
- #check for potential next-turn loss
- #check files and ranks
- for r in range(0,3):
- if brd[r].count(alt_trn) == 2 and brd[r].count(' ') == 1: return file_name[r]+rank_name[brd[r].index(' ')]
- if (brd[0][r]+brd[1][r]+brd[2][r]).count(alt_trn) == 2 and (brd[0][r]+brd[1][r]+brd[2][r]).count(' ') == 1: return file_name[(brd[0][r]+brd[1][r]+brd[2][r]).index(' ')]+rank_name[r]
-
- #check diagonals
- if (brd[0][0]+brd[1][1]+brd[2][2]).count(alt_trn) == 2 and (brd[0][0]+brd[1][1]+brd[2][2]).count(' ') == 1: return file_name[(brd[0][0]+brd[1][1]+brd[2][2]).index(' ')]+rank_name[(brd[0][0]+brd[1][1]+brd[2][2]).index(' ')]
- if (brd[0][2]+brd[1][1]+brd[2][0]).count(alt_trn) == 2 and (brd[0][2]+brd[1][1]+brd[2][0]).count(' ') == 1: return file_name[(brd[0][2]+brd[1][1]+brd[2][0]).index(' ')]+rank_name[(brd[2][0]+brd[1][1]+brd[0][2]).index(' ')]
-
- if lvl >= 3:
- random.shuffle(vic_rng)
- rng_ind = [0, 1, 2]
- #build on existing rows
- for rng in vic_rng:
- for d in range(0,3):
- if rng == file_name[d] and brd[d].count(trn) == 1 and brd[d].count(' ') == 2:
- rng_ind.remove(brd[d].index(trn))
- return file_name[d]+rank_name[rng_ind[rnd()]]
- elif rng == rank_name[d] and (brd[0][d]+brd[1][d]+brd[2][d]).count(trn) == 1 and (brd[0][d]+brd[1][d]+brd[2][d]).count(' ') == 2:
- rng_ind.remove((brd[0][d]+brd[1][d]+brd[2][d]).index(trn))
- return file_name[rng_ind[rnd()]]+rank_name[d]
- if rng == 'd1' and (brd[0][0]+brd[1][1]+brd[2][2]).count(trn) == 1 and (brd[0][0]+brd[1][1]+brd[2][2]).count(' ') == 2:
- rng_ind.remove((brd[0][0]+brd[1][1]+brd[2][2]).index(trn))
- f = rng_ind[rnd()]
- return file_name[f]+rank_name[f]
- elif rng == 'd2' and (brd[0][2]+brd[1][1]+brd[2][0]).count(trn) == 1 and (brd[0][2]+brd[1][1]+brd[2][0]).count(' ') == 2:
- rng_ind.remove((brd[0][2]+brd[1][1]+brd[2][0]).index(trn))
- f = rng_ind[rnd()]
- return file_name[f]+rank_name[2 - f]
-
- while True:
- f = rnd(2)
- r = rnd(2)
- if board[f][r] == ' ': return file_name[f]+rank_name[r]
-
-rank = [' ', ' ', ' ']
-file = [' ', ' ', ' ']
-file_name = ['a', 'b', 'c']
-rank_name = ['1', '2', '3']
-f = 0
-r = 0
-d = 0
-turn = 'X'
-vic_chk = False
-valid_move = False
-board = [file[:], file[:], file[:]]
-plrs = -1
-plrs_str = '0'
-plr = [False, False]
-plr_trn = ('X', 'O')
-one_plr = 'X'
-bot_lvl = [-1, -1]
-lvl_str = ''
-bot_lvl_name = ['Random', 'Easy', 'Medium', 'Medium_2']
-vic_rng = file_name + rank_name + ['d1', 'd2']
-rng = ''
-rng_ind = [0, 1, 2]
-
-input("""----- TIC TAC TOE -----
-Press Enter to play!
-""")
-
-while plrs > 2 or plrs < 0:
- plrs_str = input("Enter the number of players: ")
- if len(plrs_str) > 0:
- if plrs_str[0].isnumeric(): plrs = int(plrs_str[0])
-print()
-
-for r in range(0, plrs):
- plr[r] = True
-
-if plrs == 1:
- while True:
- one_plr = input("Do you want play as the X's or as the O's? ").upper()
- if len(one_plr) > 0:
- if one_plr[0] == 'X' or one_plr[0] == 'O':
- plr = [one_plr[0] == 'X', one_plr[0] == 'O']
- print()
- break
-
-if False in plr:
- for r in range(0, len(bot_lvl_name)):
- print(f"Level {r} - {bot_lvl_name[r]}")
- print()
-
-for r in range(0,2):
- while not plr[r] and bot_lvl[r] == -1:
- lvl_str = input(f"Please select {plr_trn[r]} bot level number: ")
- if len(lvl_str) > 0:
- if lvl_str[0].isnumeric(): bot_lvl[r] = int(lvl_str[0])
-
-prt_brd(board)
-
-while True:
-
- valid_move = False
- while not valid_move:
- #player uses input()
- #computer uses bot_cmd()
- if plr[turn == 'O']: cmd = input(f"{turn} to Move: ")
- else:
- cmd = bot_cmd(bot_lvl[turn == 'O'], turn, board)
- print(f"{turn} to Move: {cmd}")
- if len(cmd) == 2:
- if file_name.count(cmd[0]) == 1 and rank_name.count(cmd[1]) == 1:
- f = file_name.index(cmd[0])
- r = rank_name.index(cmd[1])
- if board[f][r] == ' ':
- board[f][r] = turn
- valid_move = True
- else: print("Illegal move")
- else: print("Invalid move")
- else: print("Invalid move")
-
- prt_brd(board)
-
- #check for victory
- #check files and ranks
- for r in range(0,3):
- if board[r].count(turn) == 3: vic_chk = True
- if (board[0][r]+board[1][r]+board[2][r]).count(turn) == 3: vic_chk = True
-
- #check diagonals
- if (board[0][0]+board[1][1]+board[2][2]).count(turn) == 3: vic_chk = True
- if (board[0][2]+board[1][1]+board[2][0]).count(turn) == 3: vic_chk = True
-
- if vic_chk: break
- if board[0].count(' ') + board[1].count(' ') + board[2].count(' ') == 0: break
-
- turn = plr_trn[turn == 'X']
-
-if vic_chk: print(f"{turn} Wins!")
-else: print("Draw")
-
-input()
-input("""----- Thank you for playing! -----
-Press Enter to exit.
-""") \ No newline at end of file
diff --git a/style.css b/style.css
index ea2eba7..fad5100 100644
--- a/style.css
+++ b/style.css
@@ -79,6 +79,13 @@ ul {
font-weight: bold;
}
+ul.projects-blog {
+ color: var(--foreground-theme-color);
+ margin-left: 2em;
+ font-size: 1em;
+ font-weight: normal;
+}
+
li {
text-indent: 0em;
font-size: 1rem;