diff --git a/.vscode/settings.json b/.vscode/settings.json
index 155422b..a0de46f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,3 @@
{
- "liveServer.settings.port": 5503
+ "liveServer.settings.port": 5504
}
\ No newline at end of file
diff --git a/UNO/Homepage.png b/UNO/Homepage.png
new file mode 100644
index 0000000..8497d18
Binary files /dev/null and b/UNO/Homepage.png differ
diff --git a/UNO/Homepage.psd b/UNO/Homepage.psd
new file mode 100644
index 0000000..eb84897
Binary files /dev/null and b/UNO/Homepage.psd differ
diff --git a/UNO/README.md b/UNO/README.md
new file mode 100644
index 0000000..04e20fc
--- /dev/null
+++ b/UNO/README.md
@@ -0,0 +1,42 @@
+# UNO Card Game (1v1):flower_playing_cards:
+**UNO** is an American shedding-type card game that is played with a specially printed deck. The game's general principles put it into the crazy eights family of card games, and it is similar to the traditional European game mau-mau. It has been a Mattel brand since 1992.
+
+🔴 Technologies used, **HTML, CSS, JS**
+
+# **Screenshots 📸**
+![UNO](https://github.com/Spandan-Bhattacharya/Solve_it/assets/125949765/89596821-cb22-4996-884b-acb36487822d)
+
+
+
+
+
+
+# How this game works:hourglass:
+
+- The game will start automatically upon loading.
+
+- The player and the CPU will each begin with 7 cards, and a number card will begin the Play Pile. The player will go first. The player can either click on a card of matching value or color to play it, play an Action Card (Reverse, Skip, Draw 2, Draw 4, Wild), or if no playable cards are available, click on the Draw Pile for a new card and forfeit their turn.
+
+- Next the CPU will play, either playing an appropriate card or taking one from the Draw Pile.
+
+- Draw 2 (+2) and Draw 4 (+4) cards will automatically add their amount to the victim's hand and advance the turn. Reverse and Skip cards will both skip the victim's turn (since there are only two players, Reverse essentially becomes a Skip). Wild cards may be played at any time.
+
+- The immediate goal is to be the first one to have no cards, at which time the opposing player's cards will be totaled and added to their score according to the following rules:
+ >numbered cards 0-9 = face value
+ >Reverse, Skip, +2 = 20pts
+ >Wild, Wild +4 = 50pts
+
+- **The first player to reach 100 loses the game.**
+
+
+## How CPU is playing!:computer:
+The CPU will have two arrays it keeps track of two arrays:
+```js
+cpuHand = []
+playableCards = []
+```
+
+Based on the last card played and it's properties, the CPU will loop through it's cpuHand array, and any card that matches either the value or color of the last card played will be pushed into the playableCards array along with any wilds the CPU may be holding.
+
+Since part of the fun and strategy is knowing when to play your Action Cards, the CPU will randomize their strategy each turn, determined by a Math.Random() variable. If the randomizer is above 0.5, the CPU will prioritize playing Action Cards in an effort to keep their losing score low. If the randomizer is below 0.5, the CPU will hold onto their Action Cards for a later turn and instead play Number Cards. There will also be logic to skip the randomizer once the player gets below a certain number of cards, at which point the CPU will only prioritize Action Cards.
+
diff --git a/UNO/audio/colorButton.wav b/UNO/audio/colorButton.wav
new file mode 100644
index 0000000..3238629
Binary files /dev/null and b/UNO/audio/colorButton.wav differ
diff --git a/UNO/audio/drawCard.wav b/UNO/audio/drawCard.wav
new file mode 100644
index 0000000..fa4a0eb
Binary files /dev/null and b/UNO/audio/drawCard.wav differ
diff --git a/UNO/audio/lose.wav b/UNO/audio/lose.wav
new file mode 100644
index 0000000..e1a4c16
Binary files /dev/null and b/UNO/audio/lose.wav differ
diff --git a/UNO/audio/playAgain.wav b/UNO/audio/playAgain.wav
new file mode 100644
index 0000000..1b95cac
Binary files /dev/null and b/UNO/audio/playAgain.wav differ
diff --git a/UNO/audio/playCard1.wav b/UNO/audio/playCard1.wav
new file mode 100644
index 0000000..4bcf8a3
Binary files /dev/null and b/UNO/audio/playCard1.wav differ
diff --git a/UNO/audio/playCard2.wav b/UNO/audio/playCard2.wav
new file mode 100644
index 0000000..74289fb
Binary files /dev/null and b/UNO/audio/playCard2.wav differ
diff --git a/UNO/audio/playCardNew.wav b/UNO/audio/playCardNew.wav
new file mode 100644
index 0000000..8a90d35
Binary files /dev/null and b/UNO/audio/playCardNew.wav differ
diff --git a/UNO/audio/plusCard.wav b/UNO/audio/plusCard.wav
new file mode 100644
index 0000000..d873b22
Binary files /dev/null and b/UNO/audio/plusCard.wav differ
diff --git a/UNO/audio/shuffle.mp3 b/UNO/audio/shuffle.mp3
new file mode 100644
index 0000000..d4a4943
Binary files /dev/null and b/UNO/audio/shuffle.mp3 differ
diff --git a/UNO/audio/shuffle.wav b/UNO/audio/shuffle.wav
new file mode 100644
index 0000000..e660a1a
Binary files /dev/null and b/UNO/audio/shuffle.wav differ
diff --git a/UNO/audio/uno.wav b/UNO/audio/uno.wav
new file mode 100644
index 0000000..905bba7
Binary files /dev/null and b/UNO/audio/uno.wav differ
diff --git a/UNO/audio/winGame.wav b/UNO/audio/winGame.wav
new file mode 100644
index 0000000..88aeefd
Binary files /dev/null and b/UNO/audio/winGame.wav differ
diff --git a/UNO/audio/winRound.wav b/UNO/audio/winRound.wav
new file mode 100644
index 0000000..88e558c
Binary files /dev/null and b/UNO/audio/winRound.wav differ
diff --git a/UNO/css/style.css b/UNO/css/style.css
new file mode 100644
index 0000000..5e799d4
--- /dev/null
+++ b/UNO/css/style.css
@@ -0,0 +1,416 @@
+*,
+*::after,
+*::before {
+ margin: 0;
+ padding: 0;
+ box-sizing: inherit;
+}
+html {
+ font-size: 62.5%;
+}
+
+ body {
+ box-sizing: border-box;
+ background-image: linear-gradient(to bottom right, #87CEEB, #1E90FF);
+ background-size: 100vw 100vh;
+ width: 100vw;
+ height: 100vh;
+ margin: auto;
+ margin-top: 50px;
+ margin-bottom: -50px;
+ font-family: 'Avenir Next';
+ position: relative;
+ }
+
+ .container {
+ position: relative;
+ }
+
+ .score-info {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+ color: white;
+ font-size: 18px;
+ text-align: right;
+ }
+
+ .cpu-box {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 100px;
+ }
+
+.cpu-box {
+ display: flex; /* NEW, Spec - Firefox, Chrome, Opera */
+ justify-content: center;
+ margin-bottom: 100px;
+}
+
+/* .cpu-hand {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 100px;
+} */
+
+.play-area {
+ display: flex;
+ justify-content: space-evenly;
+}
+
+/* .play-pile img {
+ transition: all 1s ease-in-out;
+} */
+
+.score {
+ display: flex;
+ flex-direction: column;
+ margin: auto 0;
+ color: rgb(6, 37,62);
+ font-size: x-large;
+}
+
+#seperator {
+ margin: 10px 0;
+ border: 2px solid rgb(8, 81, 140);
+}
+
+.player-box {
+ display: flex;
+ justify-content: center;
+ margin-top: 100px;
+}
+
+/* .player-hand {
+ display: flex;
+ justify-content: center;
+ margin-top: 100px;
+} */
+
+img {
+ width: 100px;
+ margin-left: -28px;
+ border-radius: 10px;
+ box-shadow: -7px -7px 14px #00405c;
+}
+
+.player-hand img:hover {
+ transform: scale(1.05) translateY(-8px);
+ transition: all 0.1s ease-in-out;
+ cursor: pointer;
+ }
+
+.player-hand img {
+ transition: all 0.1s ease-in-out; */
+}
+
+.draw-pile img:hover {
+ transform: scale(1.1);
+ transition: all 0.1s ease-in-out;
+ cursor: pointer;
+}
+
+.draw-pile img {
+ transition: all 0.1s ease-in-out;
+}
+
+#draw-card {
+ position: absolute;
+ right: 19vw;
+ z-index: 2;
+}
+
+.player-draw {
+ transform: translateY(260px) translateX(-100px);
+ transition: all 0.2s ease-in-out;
+}
+
+.cpu-draw {
+ transform: translateY(-260px) translateX(-100px);
+ transition: all 0.2s ease-in-out;
+}
+
+.player-animation {
+ position: absolute;
+ z-index: 2;
+ left: 75vw;
+ top: 600px;
+}
+
+.cpu-animation {
+ position: absolute;
+ z-index: 2;
+ left: 75vw;
+ top: 100px;
+}
+
+.play-card {
+ transform: translateY(-260px);
+ transition: 0.3s ease;
+}
+
+.cpu-play-card {
+ transform: translateY(260px);
+ transition: all 0.1s ease-in;
+}
+
+.hidden {
+ display: none;
+}
+
+.shout img {
+ transform: scale(3.5);
+ transition: all 0.1s ease-in-out;
+ border-radius: 0px;
+ box-shadow: none;
+}
+
+.player-animation img {
+ border-radius: 0px;
+ box-shadow: none;
+ transition: all 1s ease-in-out;
+}
+
+.cpu-animation img {
+ border-radius: 0px;
+ box-shadow: none;
+ transition: all 1s ease-in-out;
+}
+
+.end-of-round {
+ position: absolute;
+ z-index: 2;
+ top: 40vh;
+ left: 35vw;
+ width: 30vw;
+ margin: auto;
+ font-size: xx-large;
+ padding: 100px;
+ padding-top: 50px;
+ border: 5px solid #00eaff;
+ border-radius: 20px;
+ padding: 10px;
+ background-color: black;
+ opacity: 0.9;
+}
+
+.end-of-game {
+ position: absolute;
+ z-index: 2;
+ top: 37vh;
+ left: 30vw;
+ width: 40vw;
+ margin: auto;
+ font-size: xx-large;
+ padding: 100px;
+ padding-top: 50px;
+ border: 5px solid #00eaff;
+ border-radius: 20px;
+ padding: 10px;
+ background-color: black;
+ opacity: 0.9;
+}
+
+.end-of-round p {
+ color: #00eaff;
+ text-align: center;
+}
+
+.end-of-game p {
+ color: #00eaff;
+ text-align: center;
+}
+
+.end-of-game button {
+ background-color: greenyellow;
+ color: black;
+ margin-left: 14vw;
+ margin-top: 10px;
+
+}
+
+.color-picker {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-content: center;
+ width: 60vw;
+ margin: auto;
+ margin-top: 20px;
+ text-align: center;
+ opacity: 0;
+}
+
+.color-picker p {
+ color: rgb(134, 174, 204);
+ font-size: large;
+}
+
+ button {
+ height: 30px;
+ width: 10vw;
+ color: white;
+ border-radius: 10px;
+ transition: all 0.1s ease-in-out
+}
+
+button:hover {
+ transform: scale(1.1);
+ transition: all 0.1s ease-in-out;
+ cursor: pointer;
+}
+
+.red {
+ background-color: red;
+}
+
+.green {
+ background-color: green;
+}
+
+.blue {
+ background-color: blue;
+}
+
+.yellow {
+ background-color: yellow;
+ color: black;
+}
+
+.player-uno img {
+ border-radius: 0px;
+ box-shadow: none;
+}
+
+.cpu-uno img {
+ border-radius: 0px;
+ box-shadow: none;
+}
+
+.empty {
+ width: 100px;
+ margin-left: -28px;
+ border-radius: 10px;
+ box-shadow: none;
+}
+
+@media (max-width: 812px) {
+ body {
+ margin-top: -50px;
+ margin-bottom: 0px;
+ font-family: 'Avenir Next';
+ }
+
+ .cpu-box {
+ margin-bottom: 10px;
+ }
+
+ .play-area {
+
+ }
+
+ .play-pile img {
+ width: 100px;
+ }
+
+ .draw-pile img {
+ width: 70px;
+ margin-top: 20px;
+ }
+
+ .score {
+ font-size: large;
+ }
+
+ .player-box {
+ margin-top: 10px;
+ }
+
+ img {
+ width: 60px;
+ margin-left: 0px;
+ }
+
+ .play-card {
+ transform: translateY(-130px);
+ }
+
+ .cpu-play-card {
+ transform: translateY(130px);
+ }
+
+ .shout img {
+ transform: scale(2);
+ }
+
+ .player-draw {
+ transform: translateY(170px) translateX(-100px);
+ }
+
+ .cpu-draw {
+ transform: translateY(-170px) translateX(-100px);
+ }
+
+ .color-picker {
+ margin-top: 0px;
+ }
+
+ .color-picker p {
+ font-size: medium;
+ }
+
+ .color-picker button {
+ height: 20px;
+ }
+
+}
+@media (max-width: 812px) {
+ body {
+ margin-top: -5vw;
+ margin-bottom: 0;
+ }
+ .cpu-hand{
+ margin-top: 60px;
+ }
+ .cpu-box {
+ margin-bottom: 1vw;
+ }
+
+ img {
+ width: 6vw;
+ margin-left: 0;
+ }
+
+ .player-box {
+ margin-top: 1vw;
+ }
+
+ .play-card,
+ .cpu-play-card {
+ transform: translateY(-13vw);
+ }
+
+ .shout img {
+ transform: scale(2);
+ }
+
+ .player-draw {
+ transform: translateY(17vw) translateX(-10vw);
+ }
+
+ .cpu-draw {
+ transform: translateY(-17vw) translateX(-10vw);
+ }
+
+ .color-picker {
+ margin-top: 0;
+ }
+
+ .color-picker p {
+ font-size: 1.4rem;
+ }
+
+ .color-picker button {
+ height: 2vw;
+ }
+}
\ No newline at end of file
diff --git a/UNO/head.png b/UNO/head.png
new file mode 100644
index 0000000..76b7e3c
Binary files /dev/null and b/UNO/head.png differ
diff --git a/UNO/images/back.png b/UNO/images/back.png
new file mode 100644
index 0000000..85f69f7
Binary files /dev/null and b/UNO/images/back.png differ
diff --git a/UNO/images/blue0.png b/UNO/images/blue0.png
new file mode 100644
index 0000000..875b5c3
Binary files /dev/null and b/UNO/images/blue0.png differ
diff --git a/UNO/images/blue1.png b/UNO/images/blue1.png
new file mode 100644
index 0000000..5b24069
Binary files /dev/null and b/UNO/images/blue1.png differ
diff --git a/UNO/images/blue10.png b/UNO/images/blue10.png
new file mode 100644
index 0000000..572f161
Binary files /dev/null and b/UNO/images/blue10.png differ
diff --git a/UNO/images/blue11.png b/UNO/images/blue11.png
new file mode 100644
index 0000000..207d0e3
Binary files /dev/null and b/UNO/images/blue11.png differ
diff --git a/UNO/images/blue12.png b/UNO/images/blue12.png
new file mode 100644
index 0000000..46d96cb
Binary files /dev/null and b/UNO/images/blue12.png differ
diff --git a/UNO/images/blue2.png b/UNO/images/blue2.png
new file mode 100644
index 0000000..c92152d
Binary files /dev/null and b/UNO/images/blue2.png differ
diff --git a/UNO/images/blue3.png b/UNO/images/blue3.png
new file mode 100644
index 0000000..cfb0b6b
Binary files /dev/null and b/UNO/images/blue3.png differ
diff --git a/UNO/images/blue4.png b/UNO/images/blue4.png
new file mode 100644
index 0000000..6bbb35e
Binary files /dev/null and b/UNO/images/blue4.png differ
diff --git a/UNO/images/blue5.png b/UNO/images/blue5.png
new file mode 100644
index 0000000..47166f6
Binary files /dev/null and b/UNO/images/blue5.png differ
diff --git a/UNO/images/blue6.png b/UNO/images/blue6.png
new file mode 100644
index 0000000..ba6b724
Binary files /dev/null and b/UNO/images/blue6.png differ
diff --git a/UNO/images/blue7.png b/UNO/images/blue7.png
new file mode 100644
index 0000000..8f966a3
Binary files /dev/null and b/UNO/images/blue7.png differ
diff --git a/UNO/images/blue8.png b/UNO/images/blue8.png
new file mode 100644
index 0000000..e62879d
Binary files /dev/null and b/UNO/images/blue8.png differ
diff --git a/UNO/images/blue9.png b/UNO/images/blue9.png
new file mode 100644
index 0000000..0d282a2
Binary files /dev/null and b/UNO/images/blue9.png differ
diff --git a/UNO/images/empty.png b/UNO/images/empty.png
new file mode 100644
index 0000000..9a8a1c7
Binary files /dev/null and b/UNO/images/empty.png differ
diff --git a/UNO/images/green0.png b/UNO/images/green0.png
new file mode 100644
index 0000000..e1344e9
Binary files /dev/null and b/UNO/images/green0.png differ
diff --git a/UNO/images/green1.png b/UNO/images/green1.png
new file mode 100644
index 0000000..c939b89
Binary files /dev/null and b/UNO/images/green1.png differ
diff --git a/UNO/images/green10.png b/UNO/images/green10.png
new file mode 100644
index 0000000..c511e20
Binary files /dev/null and b/UNO/images/green10.png differ
diff --git a/UNO/images/green11.png b/UNO/images/green11.png
new file mode 100644
index 0000000..e9e4a0a
Binary files /dev/null and b/UNO/images/green11.png differ
diff --git a/UNO/images/green12.png b/UNO/images/green12.png
new file mode 100644
index 0000000..e9bdc0f
Binary files /dev/null and b/UNO/images/green12.png differ
diff --git a/UNO/images/green2.png b/UNO/images/green2.png
new file mode 100644
index 0000000..22ddc77
Binary files /dev/null and b/UNO/images/green2.png differ
diff --git a/UNO/images/green3.png b/UNO/images/green3.png
new file mode 100644
index 0000000..7cac4ba
Binary files /dev/null and b/UNO/images/green3.png differ
diff --git a/UNO/images/green4.png b/UNO/images/green4.png
new file mode 100644
index 0000000..542fb40
Binary files /dev/null and b/UNO/images/green4.png differ
diff --git a/UNO/images/green5.png b/UNO/images/green5.png
new file mode 100644
index 0000000..107e823
Binary files /dev/null and b/UNO/images/green5.png differ
diff --git a/UNO/images/green6.png b/UNO/images/green6.png
new file mode 100644
index 0000000..aa56a49
Binary files /dev/null and b/UNO/images/green6.png differ
diff --git a/UNO/images/green7.png b/UNO/images/green7.png
new file mode 100644
index 0000000..2e66eb9
Binary files /dev/null and b/UNO/images/green7.png differ
diff --git a/UNO/images/green8.png b/UNO/images/green8.png
new file mode 100644
index 0000000..94be934
Binary files /dev/null and b/UNO/images/green8.png differ
diff --git a/UNO/images/green9.png b/UNO/images/green9.png
new file mode 100644
index 0000000..a0c68a3
Binary files /dev/null and b/UNO/images/green9.png differ
diff --git a/UNO/images/red0.png b/UNO/images/red0.png
new file mode 100644
index 0000000..88e50eb
Binary files /dev/null and b/UNO/images/red0.png differ
diff --git a/UNO/images/red1.png b/UNO/images/red1.png
new file mode 100644
index 0000000..bc5cdd0
Binary files /dev/null and b/UNO/images/red1.png differ
diff --git a/UNO/images/red10.png b/UNO/images/red10.png
new file mode 100644
index 0000000..2948e3e
Binary files /dev/null and b/UNO/images/red10.png differ
diff --git a/UNO/images/red11.png b/UNO/images/red11.png
new file mode 100644
index 0000000..3ccdb08
Binary files /dev/null and b/UNO/images/red11.png differ
diff --git a/UNO/images/red12.png b/UNO/images/red12.png
new file mode 100644
index 0000000..72005a1
Binary files /dev/null and b/UNO/images/red12.png differ
diff --git a/UNO/images/red2.png b/UNO/images/red2.png
new file mode 100644
index 0000000..6123265
Binary files /dev/null and b/UNO/images/red2.png differ
diff --git a/UNO/images/red3.png b/UNO/images/red3.png
new file mode 100644
index 0000000..ae46e79
Binary files /dev/null and b/UNO/images/red3.png differ
diff --git a/UNO/images/red4.png b/UNO/images/red4.png
new file mode 100644
index 0000000..ad05ee2
Binary files /dev/null and b/UNO/images/red4.png differ
diff --git a/UNO/images/red5.png b/UNO/images/red5.png
new file mode 100644
index 0000000..eaec5bf
Binary files /dev/null and b/UNO/images/red5.png differ
diff --git a/UNO/images/red6.png b/UNO/images/red6.png
new file mode 100644
index 0000000..5790237
Binary files /dev/null and b/UNO/images/red6.png differ
diff --git a/UNO/images/red7.png b/UNO/images/red7.png
new file mode 100644
index 0000000..1517f14
Binary files /dev/null and b/UNO/images/red7.png differ
diff --git a/UNO/images/red8.png b/UNO/images/red8.png
new file mode 100644
index 0000000..db0927d
Binary files /dev/null and b/UNO/images/red8.png differ
diff --git a/UNO/images/red9.png b/UNO/images/red9.png
new file mode 100644
index 0000000..9f2c7d7
Binary files /dev/null and b/UNO/images/red9.png differ
diff --git a/UNO/images/uno!.png b/UNO/images/uno!.png
new file mode 100644
index 0000000..9a247ff
Binary files /dev/null and b/UNO/images/uno!.png differ
diff --git a/UNO/images/uno.jpeg b/UNO/images/uno.jpeg
new file mode 100644
index 0000000..27b217a
Binary files /dev/null and b/UNO/images/uno.jpeg differ
diff --git a/UNO/images/wild13.png b/UNO/images/wild13.png
new file mode 100644
index 0000000..780fe8d
Binary files /dev/null and b/UNO/images/wild13.png differ
diff --git a/UNO/images/wild14.png b/UNO/images/wild14.png
new file mode 100644
index 0000000..34402df
Binary files /dev/null and b/UNO/images/wild14.png differ
diff --git a/UNO/images/yellow0.png b/UNO/images/yellow0.png
new file mode 100644
index 0000000..b1ab0e7
Binary files /dev/null and b/UNO/images/yellow0.png differ
diff --git a/UNO/images/yellow1.png b/UNO/images/yellow1.png
new file mode 100644
index 0000000..1795927
Binary files /dev/null and b/UNO/images/yellow1.png differ
diff --git a/UNO/images/yellow10.png b/UNO/images/yellow10.png
new file mode 100644
index 0000000..327b8c0
Binary files /dev/null and b/UNO/images/yellow10.png differ
diff --git a/UNO/images/yellow11.png b/UNO/images/yellow11.png
new file mode 100644
index 0000000..397b5cd
Binary files /dev/null and b/UNO/images/yellow11.png differ
diff --git a/UNO/images/yellow12.png b/UNO/images/yellow12.png
new file mode 100644
index 0000000..36a5bb7
Binary files /dev/null and b/UNO/images/yellow12.png differ
diff --git a/UNO/images/yellow2.png b/UNO/images/yellow2.png
new file mode 100644
index 0000000..913551e
Binary files /dev/null and b/UNO/images/yellow2.png differ
diff --git a/UNO/images/yellow3.png b/UNO/images/yellow3.png
new file mode 100644
index 0000000..116868a
Binary files /dev/null and b/UNO/images/yellow3.png differ
diff --git a/UNO/images/yellow4.png b/UNO/images/yellow4.png
new file mode 100644
index 0000000..b2dc74a
Binary files /dev/null and b/UNO/images/yellow4.png differ
diff --git a/UNO/images/yellow5.png b/UNO/images/yellow5.png
new file mode 100644
index 0000000..53b9721
Binary files /dev/null and b/UNO/images/yellow5.png differ
diff --git a/UNO/images/yellow6.png b/UNO/images/yellow6.png
new file mode 100644
index 0000000..034bc03
Binary files /dev/null and b/UNO/images/yellow6.png differ
diff --git a/UNO/images/yellow7.png b/UNO/images/yellow7.png
new file mode 100644
index 0000000..ba13602
Binary files /dev/null and b/UNO/images/yellow7.png differ
diff --git a/UNO/images/yellow8.png b/UNO/images/yellow8.png
new file mode 100644
index 0000000..af63d5b
Binary files /dev/null and b/UNO/images/yellow8.png differ
diff --git a/UNO/images/yellow9.png b/UNO/images/yellow9.png
new file mode 100644
index 0000000..e6b7133
Binary files /dev/null and b/UNO/images/yellow9.png differ
diff --git a/UNO/index.html b/UNO/index.html
new file mode 100644
index 0000000..abf1baa
--- /dev/null
+++ b/UNO/index.html
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+ UNO Card Game
+
+
+
+
+
+
+
+
+
+
+
ROBO: 249
+
+
PLAYER: 67
+
The first player to reach 100 points, will lose the game
+
+
+
+
+
+
+
+
+
+
+
+
X won the game!
+
+
+
+
+
+
+
+
+
+
+
+
+
Select a color:
+
+
+
+
+
+
+
+
+
+
diff --git a/UNO/js/app.js b/UNO/js/app.js
new file mode 100644
index 0000000..601ebb8
--- /dev/null
+++ b/UNO/js/app.js
@@ -0,0 +1,939 @@
+console.log('uno!')
+
+//#region // DOM AND GLOBAL VARIABLES
+const cpuHandDom = document.querySelector('.cpu-hand')
+const playerHandDom = document.querySelector('.player-hand')
+
+const cpuScoreDom = document.querySelector('#cpu-score')
+const playerScoreDom = document.querySelector('#player-score')
+
+const playPileDom = document.querySelector('.play-pile')
+const drawPileDom = document.querySelector('.draw-pile')
+
+const playerUno = document.querySelector('.player-animation')
+const cpuUno = document.querySelector('.cpu-animation')
+
+// hand arrays
+const cpuHand = []
+const playerHand = []
+
+const deck = []
+let playPile
+let cpuScore = 0
+let playerScore = 0
+
+// variables to control gameplay
+let playerTurn = true
+let gameOn = true
+let colorPickerIsOpen = false
+let cpuDelay = Math.floor((Math.random() * cpuHand.length * 200) + 1500)
+let gameOver = 100
+//#endregion
+
+//#region preload imgs for faster loading
+const imgPreLoad = []
+let preLoaded = false
+
+const preLoadImgs = () => {
+ for (let i = 0; i <= 3; i++) {
+ let color
+ if (i === 0) color = 'red'
+ if (i === 1) color = 'green'
+ if (i === 2) color = 'blue'
+ if (i === 3) color = 'yellow'
+ for (let n = 0; n <= 14; n++) {
+ let img = new Image()
+ img.src = 'images/' + color + i + '.png'
+ imgPreLoad.push(img)
+ }
+ }
+
+ for (let i = 0; i < imgPreLoad.length; i++) {
+ playPileDom.appendChild(imgPreLoad[i])
+ playPileDom.innerHTML = ''
+ }
+}
+//#endregion
+
+// #region AUDIO
+const shuffleFX = new Audio('audio/shuffle.wav')
+const playCardFX = new Audio('audio/playCardNew.wav')
+const playCardFX2 = new Audio('audio/playCard2.wav')
+const drawCardFX = new Audio('audio/drawCard.wav')
+const winRoundFX = new Audio('audio/winRound.wav')
+const winGameFX = new Audio('audio/winGame.wav')
+const loseFX = new Audio('audio/lose.wav')
+const plusCardFX = new Audio('audio/plusCard.wav')
+const unoFX = new Audio('audio/uno.wav')
+const colorButton = new Audio('audio/colorButton.wav')
+const playAgain = new Audio('audio/playAgain.wav')
+
+const pickPlayCardSound = () => {
+ // const random = Math.random() * 10
+
+ // if (random > 6) playCardFX.play()
+ // else playCardFX2.play()
+
+ playCardFX2.play()
+}
+//#endregion
+
+// #region CARD AND DECK MANAGEMENT
+class Card {
+ constructor(rgb, value, points, changeTurn, drawValue, imgSrc) {
+ this.color = rgb
+ this.value = value
+ this.points = points
+ this.changeTurn = changeTurn
+ this.drawValue = drawValue
+ this.src = imgSrc
+ this.playedByPlayer = false
+ }
+}
+
+const createCard = (rgb, color) => {
+ for (let i = 0; i <= 14; i++) {
+ // number cards
+ if (i === 0) {
+ deck.push(new Card(rgb, i, i, true, 0, 'images/' + color + i + '.png'))
+ }
+ else if (i > 0 && i <= 9) {
+ deck.push(new Card(rgb, i, i, true, 0, 'images/' + color + i + '.png'))
+ deck.push(new Card(rgb, i, i, true, 0, 'images/' + color + i + '.png'))
+ }
+ // reverse/skip
+ else if (i === 10 || i === 11) {
+ deck.push(new Card(rgb, i, 20, false, 0, 'images/' + color + i + '.png'))
+ deck.push(new Card(rgb, i, 20, false, 0, 'images/' + color + i + '.png'))
+ }
+ // draw 2
+ else if (i === 12) {
+ deck.push(new Card(rgb, i, 20, false, 2, 'images/' + color + i + '.png'))
+ deck.push(new Card(rgb, i, 20, false, 2, 'images/' + color + i + '.png'))
+ }
+ else if (i === 13) {
+ deck.push(new Card('any', i, 50, true, 0, 'images/wild' + i + '.png'))
+ }
+ else {
+ deck.push(new Card('any', i, 50, false, 4, 'images/wild' + i + '.png'))
+ }
+ }
+}
+
+const createDeck = () => {
+ // destroy previous deck
+ deck.length = 0
+ // create new deck
+ for (let i = 0; i <= 3; i++){
+ if (i === 0) {
+ createCard('rgb(255, 6, 0)', 'red')
+ }
+ else if (i === 1) {
+ createCard('rgb(0, 170, 69)', 'green')
+ }
+ else if (i === 2) {
+ createCard('rgb(0, 150, 224)', 'blue')
+ }
+ else {
+ createCard('rgb(255, 222, 0)', 'yellow')
+ }
+ }
+
+ console.log(deck) // TODO: remove
+}
+
+const shuffleDeck = (deck) => {
+ // Fisher-Yates Method - https://www.frankmitchell.org/2015/01/fisher-yates/
+ console.log('shuffling', deck) // TODO: remove
+
+ for (let i = deck.length - 1; i > 0; i--) {
+ deck[i].playedByPlayer = false
+ let j = Math.floor(Math.random() * (i + 1))
+ let temp = deck[i]
+ deck[i] = deck[j]
+ deck[j] = temp
+ }
+ console.log(deck, 'shuffled') // TODO: remove
+ shuffleFX.play()
+}
+//#endregion
+
+// #region GAME BEHAVIOURS
+const dealCards = () => {
+ for (let i = 0; i < 7; i++) {
+ // deal cards into cpu/player arrays
+ cpuHand.push(deck.shift())
+ playerHand.push(deck.shift())
+
+ // put cards on the DOM
+ const cpuCard = document.createElement('img')
+ cpuCard.setAttribute('src', 'images/back.png')
+ cpuCard.setAttribute('class', 'cpu')
+ cpuHandDom.appendChild(cpuCard)
+
+ const playerCard = document.createElement('img')
+ playerCard.setAttribute('src', playerHand[i].src)
+ playerCard.setAttribute('class', 'player')
+
+ // assign cards an id = their index in the playerHand array
+ //in order to reference the correct card object
+ playerCard.setAttribute('id', i)
+ playerHandDom.appendChild(playerCard)
+ }
+}
+
+const startPlayPile = () => {
+ const playCard = document.createElement('img')
+
+ // find first card that isn't an action card
+ for (let i = 0; i < deck.length; i++) {
+ if (deck[i].color !== "any" && deck[i].value <= 9) {
+ // begin playPile array with first valid card
+ playPile = deck.splice(i, 1)
+ break
+ }
+ }
+
+ // set playCard to correct image
+ playCard.setAttribute('src', playPile[0].src)
+ // play card to the playPile
+ playPileDom.appendChild(playCard)
+}
+
+const newHand = () => {
+ console.log('new hand')
+ gameOn = true
+ // clear hands and play pile
+ cpuHandDom.innerHTML = ''
+ cpuHand.length = 0
+ playerHandDom.innerHTML = ''
+ playerHand.length = 0
+ playPileDom.innerHTML = ''
+
+ // create new deck
+ createDeck()
+ // shuffle deck
+ shuffleDeck(deck)
+ // deal cards and first play card
+ dealCards()
+ // set down first play card that isn't an action card
+ startPlayPile()
+
+ if (colorPickerIsOpen) hideColorPicker()
+}
+
+const updatePlayPileDom = () => {
+ playPileDom.innerHTML = ''
+
+ // add played card to playPile
+ const newCardImg = document.createElement('img')
+ const imgSrc = playPile[playPile.length - 1].src
+ newCardImg.setAttribute('src', imgSrc)
+ playPileDom.appendChild(newCardImg)
+}
+
+const updateHand = (handToUpdate) => {
+ let domToUpdate, cardClass;
+
+ if (handToUpdate === cpuHand) {
+ domToUpdate = cpuHandDom
+ cardClass = 'cpu'
+ if (cpuVisible) cpuVisible = false
+ }
+ else {
+ domToUpdate = playerHandDom
+ cardClass = 'player'
+ }
+
+ // clear the selected dom
+ domToUpdate.innerHTML = ''
+
+ // update dom
+ for (let i = 0; i < handToUpdate.length; i++) {
+ let src
+
+ if (domToUpdate === cpuHandDom) {
+ src = 'images/back.png'
+ }
+ else {
+ src = handToUpdate[i].src
+ }
+
+ const updatedCard = document.createElement('img')
+ updatedCard.setAttribute('src', src)
+ updatedCard.setAttribute('class', cardClass)
+ // update ID's to match playerHand indexes
+ updatedCard.setAttribute('id', i)
+ domToUpdate.appendChild(updatedCard)
+ }
+
+ // keep dom element from collapsing when hand is empty
+ if (handToUpdate.length === 0) {
+ const updatedCard = document.createElement('img')
+ updatedCard.setAttribute('src', 'images/empty.png')
+ updatedCard.setAttribute('class', 'empty')
+ // update ID's to match playerHand indexes
+ domToUpdate.appendChild(updatedCard)
+ }
+}
+
+const drawCard = (handGetsCard) => {
+ animateDrawCard(handGetsCard)
+ // check if the deck has card to draw
+ if (deck.length > 0) {
+ // pull the top card
+ const newCard = deck.shift()
+ handGetsCard.push(newCard)
+ console.log(handGetsCard, 'drew one card') // TODO: remove
+
+ }
+ else {
+ // shuffle playPile
+ shuffleDeck(playPile)
+ for (let i = 0; i <= playPile.length - 1; i++) {
+ // shuffled playPile becomes the new deck
+ deck.push(playPile[i])
+ }
+ // leave the last played card on the playPile
+ playPile.length = 1
+
+ // pull the top card from the deck
+ const newCard = deck.shift()
+ handGetsCard.push(newCard)
+ console.log(handGetsCard, 'drew one card') // TODO: remove
+
+ }
+ drawCardFX.play()
+ setTimeout(() => {
+ updateHand(handGetsCard)
+ }, 500)
+}
+
+const animateDrawCard = (player) => {
+ let playerClass
+ if (player === cpuHand) playerClass = 'cpu-draw'
+ else playerClass = 'player-draw'
+
+ const drawCardEl = document.querySelector('#draw-card')
+ drawCardEl.classList.remove('hidden')
+ setTimeout(() => {
+ drawCardEl.classList.add(playerClass)
+ setTimeout(() => {
+ drawCardEl.classList.add('hidden')
+ drawCardEl.classList.remove(playerClass)
+ clearInterval()
+ }, 500)
+ }, 30)
+}
+
+const showUno = (unoHand) => {
+ // remove hidden class from player-uno div
+ unoHand.classList.remove('hidden')
+ unoFX.play()
+ console.log('removed HIDDEN from', unoHand)
+
+ // add shout class
+ setTimeout(() => {
+ unoHand.classList.add('shout')
+ console.log('added SHOUT to', unoHand)
+ //setTimeout = after x seconds remove shout
+ setTimeout(() => {
+ unoHand.classList.remove('shout')
+ console.log('removed SHOUT from', unoHand)
+
+ setTimeout(() => {
+ unoHand.classList.add('hidden')
+ console.log('added HIDDEN to', unoHand)
+ }, 1000)
+ }, 1000)
+ }, 10)
+}
+
+const showColorPicker = () => {
+ // show the color picker
+ const colorPicker = document.querySelector('.color-picker')
+ colorPicker.style.opacity = 1
+ colorPickerIsOpen = true
+
+ //assign eventHandler's to buttons
+ document.querySelector('.red').addEventListener('click', (e) => {
+ // pass thru the class name for color
+ chooseColor('rgb(255, 6, 0)')
+ })
+ document.querySelector('.green').addEventListener('click', (e) => {
+ // pass thru the class name for color
+ chooseColor('rgb(0, 170, 69)')
+ })
+ document.querySelector('.blue').addEventListener('click', (e) => {
+ // pass thru the class name for color
+ chooseColor('rgb(0, 150, 224)')
+ })
+ document.querySelector('.yellow').addEventListener('click', (e) => {
+ // pass thru the class name for color
+ chooseColor('rgb(255, 222, 0)')
+ })
+}
+
+const chooseColor = (rgb) => {
+ //assign the color to the wild on top of the play pile
+ colorButton.play()
+ playPile[playPile.length - 1].color = rgb
+
+ // hide the color picker
+ hideColorPicker()
+ playerTurn = false;
+ setTimeout(playCPU, cpuDelay)}
+
+function hideColorPicker() {
+ const colorPicker = document.querySelector('.color-picker')
+ colorPicker.style.opacity = 0
+ colorPickerIsOpen = false
+}
+
+const skipOrEndTurn = () => {
+ // check if changeTurn or skip
+ if (playPile[playPile.length - 1].changeTurn) {
+ playerTurn = false
+
+ // cpu's turn
+ setTimeout(playCPU, cpuDelay)
+ }
+}
+
+// update player names with whose turn it is
+const showTurnOnDom = () => {
+ if (playerTurn) {
+ document.querySelector('.player-score-title').style.color = 'rgb(100, 150, 150)'
+ document.querySelector('.cpu-score-title').style.color = 'rgb(6, 37, 62)'
+ }
+ else {
+ document.querySelector('.player-score-title').style.color = 'rgb(6, 37, 62)'
+ document.querySelector('.cpu-score-title').style.color = 'rgb(100, 150, 150)'
+ }
+}
+//#endregion
+
+//#region END OF ROUND/GAME FUNCTIONS
+const tallyPoints = (loserHand) => {
+ let points = 0
+
+ for (const card of loserHand) {
+ points += card.points
+ }
+
+ if (loserHand == cpuHand) {
+ cpuScore += points
+ }
+ else {
+ playerScore += points
+ }
+}
+
+const updateScores = () => {
+ // update cpuScoreDom
+ cpuScoreDom.innerHTML = cpuScore
+ if (cpuScore < gameOver / 2) cpuScoreDom.style.color = 'rgb(0, 140, 0)'
+ else cpuScoreDom.style.color = 'rgb(121, 2, 2)'
+
+ // update playerScoreDom
+ playerScoreDom.innerHTML = playerScore
+ if (playerScore < gameOver / 2) playerScoreDom.style.color = 'rgb(0, 140, 0)'
+ else playerScoreDom.style.color = 'rgb(121, 2, 2)'
+}
+
+const checkForWinner = () => {
+ // check if that no one has lost
+ if (playerScore < gameOver && cpuScore < gameOver) {
+ // next round
+ if (playerHand.length === 0) {
+ winRoundFX.play()
+ endRound(playerHand)
+ }
+ if (cpuHand.length === 0) {
+ loseFX.play()
+ endRound(cpuHand)
+ }
+ }
+
+ else {
+ // game over
+ endGame()
+ }
+}
+
+const showCpuCards = () => {
+ if (cpuHand.length >= 1) {
+ cpuHandDom.innerHTML = ''
+ for (let i = 0; i < cpuHand.length; i++) {
+
+ // turn the cards over
+ const cpuCard = document.createElement('img')
+ cpuCard.setAttribute('src', cpuHand[i].src)
+ cpuCard.setAttribute('class', 'cpu')
+ cpuHandDom.appendChild(cpuCard)
+ }
+ }
+}
+
+const hideCpuCards = () => {
+ if (cpuHand.length >= 1) {
+ cpuHandDom.innerHTML = ''
+ for (let i = 0; i < cpuHand.length; i++) {
+
+ // turn the cards over
+ const cpuCard = document.createElement('img')
+ cpuCard.setAttribute('src', 'images/back.png')
+ cpuCard.setAttribute('class', 'cpu')
+ cpuHandDom.appendChild(cpuCard)
+ }
+ }
+}
+
+const endRound = (winner) => {
+ console.log('round over') // TODO: remove
+ gameOn = false;
+ playerTurn = !playerTurn
+
+ if (cpuHand.length > 0) showCpuCards()
+
+ const endOfroundDom = document.querySelector('.end-of-round')
+ const roundDom = document.querySelector('.round')
+
+ // show end of round element & format it based on who won
+ endOfroundDom.classList.remove('hidden')
+ if (winner === playerHand) roundDom.textContent = 'You won the round!'
+ else roundDom.textContent = 'CPU won the round...'
+
+ // hide end of round element after 2 seconds
+ setTimeout(() => {
+ endOfroundDom.classList.add('hidden')
+ playerTurn = !playerTurn
+ newHand()
+ if (!playerTurn) setTimeout(playCPU, cpuDelay)
+
+ }, 3000)
+}
+
+const endGame = () => {
+ console.log('game over') // TODO: remove
+ gameOn = false;
+ if (cpuHand.length > 0) showCpuCards()
+
+ const endOfGameDom = document.querySelector('.end-of-game')
+ const gameDom = document.querySelector('.game')
+
+ // show end of game element & format based on winner
+ endOfGameDom.classList.remove('hidden')
+
+ if (playerScore > gameOver) {
+ loseFX.play()
+ gameDom.textContent = 'CPU won the game... Play again?'
+ }
+ else {
+ winGameFX.play()
+ gameDom.textContent = 'You won the game! Play again?'
+ }
+
+ // add event listener to 'play again' button
+ document.querySelector('.play-again').addEventListener('click', () => {
+ playAgain.play()
+ // hide end of game element on click
+ endOfGameDom.classList.add('hidden')
+ playerScore = 0
+ cpuScore = 0
+ updateScores()
+ playerTurn = !playerTurn
+ newHand()
+ if (!playerTurn) setTimeout(playCPU, cpuDelay)
+ })
+}
+//#endregion
+
+//#region ////////CPU LOGIC////////
+const letCpuDrawCards = () => {
+ if (playPile[playPile.length - 1].drawValue > 0) {
+ // add however many cards based on drawValue of last played card
+ for (let i = 0; i < playPile[playPile.length - 1].drawValue; i++) {
+ drawCard(cpuHand)
+ }
+ }
+}
+
+const playCPU = () => {
+ if (!playerTurn && gameOn) {
+ console.log('cpu beginning turn') // TODO: remove
+
+ // create temp array of playable cards based on last card played
+ const playable = determinePlayableCards()
+
+ // if no playable cards
+ if (playable.length === 0) {
+ console.log('CPU has no cards to play') // TODO: remove
+ // draw card
+ drawCard(cpuHand)
+ // end turn
+ setTimeout(() => {
+ console.log('CPU ending turn') // TODO: remove
+ playerTurn = true
+ return
+ }, 500)
+ }
+ //if one playable card
+ else if (playable.length === 1) {
+ // chosenCard = playable[0]
+ setTimeout(playCPUCard, 300, playable[0])
+
+ //playCPUCard(playable[0])
+ }
+ // if more than one playable cards
+ else if (playable.length > 1) {
+ console.log('cpu has', playable.length, 'playable cards')
+
+ let chosenCard = runStrategist(playable)
+ setTimeout(playCPUCard, 300, chosenCard)
+
+
+ //playCPUCard(chosenCard)
+ }
+ }
+//#region CPU SPECIFIC FUNCTIONS
+ function determinePlayableCards() {
+ const playableCards = []
+
+ console.log('last card played:') // TODO: remove
+ console.log(playPile[playPile.length - 1])
+ for (let i = 0; i < cpuHand.length; i++) {
+ if (cpuHand[i].color === playPile[playPile.length - 1].color || cpuHand[i].value === playPile[playPile.length - 1].value || cpuHand[i].color === 'any' || playPile[playPile.length - 1].color === 'any') {
+ let validCard = cpuHand.splice(i, 1)
+ playableCards.push(validCard[0])
+ }
+ }
+ console.log('playable cards:')
+ console.log(playableCards) // TODO: remove
+
+ return playableCards
+}
+
+ function runStrategist(playable) {
+ let cardIndex
+
+ // run strategist to determine strategy
+ let strategist = Math.random()
+ console.log('strategist:', strategist) // TODO: remove
+ // if strategist > 0.5 || playerHand <= 3
+ if (playPile.length > 2 && (strategist > 0.7 || playerHand.length < 3 || cpuHand.length > (playerHand.length * 2) || (playPile[playPile.length - 1].playedByPlayer === true && playPile[playPile.length - 1].drawValue > 0) || (playPile[playPile.length - 2].playedByPlayer === true && playPile[playPile.length - 1].drawValue > 0))) {
+ // prioritize action/high point cards
+ console.log('cpu chose high card') // TODO: remove
+ let highestValue = 0
+
+ for (let i = 0; i < playable.length; i++){
+ if (playable[i].value > highestValue) {
+ highestValue = playable[i].value
+ cardIndex = i
+ }
+ }
+
+ // play card determined by strategist
+ // remove card from playable
+ chosenCard = playable.splice(cardIndex, 1)
+
+ // return playable to cpuHand
+ returnPlayablesToHand()
+ }
+ else {
+ // else prioritize color || number cards
+ console.log('cpu chose low card') // TODO: remove
+ let lowestValue = 14
+
+ for (let i = 0; i < playable.length; i++){
+ if (playable[i].value < lowestValue) {
+ lowestValue = playable[i].value
+ cardIndex = i
+ }
+ }
+
+ // play card determined by strategist
+ // remove card from playable
+ chosenCard = playable.splice(cardIndex, 1)
+
+ returnPlayablesToHand()
+ }
+
+ console.log(chosenCard[0]) // TODO: remove
+ return chosenCard[0]
+
+ function returnPlayablesToHand() {
+ if (playable.length > 0) {
+ for (const card of playable) {
+ cpuHand.push(card)
+ }
+ }
+ }
+ }
+
+ function playCPUCard(chosenCard) {
+ console.log('playing card:') // TODO: remove
+ console.log(chosenCard)
+
+ //animate random card from cpuHandDom
+ const cpuDomCards = cpuHandDom.childNodes
+ cpuDomCards[Math.floor(Math.random() * cpuDomCards.length)].classList.add('cpu-play-card')
+ console.log('animating CPU card')
+ pickPlayCardSound()
+ // debugger
+
+ setTimeout(() => {
+ playPile.push(chosenCard)
+ // update playPileDom
+ updatePlayPileDom()
+
+ // check if cpu played wild
+ if (playPile[playPile.length - 1].color === 'any' && playPile[playPile.length - 1].drawValue === 0 && playPile[playPile.length - 1].playedByPlayer === false) {
+ console.log('cpu played a wild') // TODO: remove
+ chooseColorAfterWild()
+ }
+
+ // check cpuHand length and update cpuHandDom
+ if (cpuHand.length >= 1) {
+ updateHand(cpuHand)
+ if (cpuHand.length === 1) {
+ showUno(cpuUno)
+ }
+ }
+ // if end of round
+ else {
+ // tallyPoints(playerHand)
+ // updateScores()
+ // checkForWinner()
+ updateHand(cpuHand)
+ setTimeout(() => {
+ tallyPoints(playerHand)
+ updateScores()
+ checkForWinner()
+ }, 1200)
+ }
+
+ // if cpu played a draw card
+ if (chosenCard.drawValue > 0) {
+ // alert('cpu played a +' + chosenCard.drawValue + ' card!')
+ console.log('cpu played a +' + chosenCard.drawValue + ' card!') // TODO: remove
+ hitWithDrawCard()
+ setTimeout(() => {
+ for (let i = 0; i < chosenCard.drawValue; i++) {
+ drawCard(playerHand)
+ }
+ checkChangeTurn()
+ },1000)
+ }
+ // else checkChangeTurn()
+ else setTimeout(checkChangeTurn, 500)
+ }, 500)
+
+
+ function checkChangeTurn() {
+ if (chosenCard.changeTurn) {
+ // if changeTurn, playerTurn = true
+ console.log('cpu has finished its turn') // TODO: remove
+ playerTurn = true
+ return
+ }
+ else {
+ // else cpuTurn() again
+ console.log('cpu goes again') // TODO: remove
+ setTimeout(playCPU, cpuDelay)
+ }
+ }
+ }
+
+ function chooseColorAfterWild() {
+ console.log('cpu picking new color') // TODO: remove
+ const colors = ['rgb(255, 6, 0)', 'rgb(0, 170, 69)', 'rgb(0, 150, 224)', 'rgb(255, 222, 0)']
+ const colorsInHand = [0, 0, 0, 0]
+
+ // cpu checks how many of each color it has
+ for (const card of cpuHand) {
+ if (card.color === colors[0]) colorsInHand[0]++
+ if (card.color === colors[1]) colorsInHand[1]++
+ if (card.color === colors[2]) colorsInHand[2]++
+ if (card.color === colors[3]) colorsInHand[3]++
+ }
+
+ // find the index of the max value
+ let indexOfMax = colorsInHand.indexOf(Math.max(...colorsInHand))
+
+ // style the wild card and it's color
+ const wildCardDom = playPileDom.childNodes[0]
+ wildCardDom.style.border = '5px solid ' + colors[indexOfMax]
+ wildCardDom.style.width = '105px'
+ playPile[playPile.length - 1].color = colors[indexOfMax]
+ }
+ //#endregion
+}
+
+const hitWithDrawCard = () => {
+ plusCardFX.play()
+ playPileDom.classList.add('shout')
+ setTimeout(() => {
+ playPileDom.classList.remove('shout')
+ }, 1000)
+}
+//#endregion
+
+const playPlayerCard = (index) => {
+ let cardToPlay = playerHand.splice(index, 1)
+ cardToPlay[0].playedByPlayer = true
+ playPile.push(cardToPlay[0])
+
+ // clear the playPile
+ updatePlayPileDom()
+}
+
+//#region ///////MAIN GAME FUNCTION////////
+const startGame = () => {
+ if (!preLoaded) {
+ preLoadImgs()
+ preLoaded = true
+ }
+
+ playerScore = 0
+ cpuScore = 0
+
+ listenForDevMode()
+ setInterval(showTurnOnDom, 100)
+ newHand()
+ updateScores()
+
+ if (!playerTurn) setTimeout(playCPU, cpuDelay)
+
+
+ // set event listeners on playerHandDom and drawPileDom
+ // playerHandDom
+ playerHandDom.addEventListener('click', (event) => {
+ if (playerTurn && !colorPickerIsOpen && event.target.getAttribute('id')) {
+
+ const lastCardDom = playPileDom.childNodes[0]
+ if (lastCardDom.style !== '100px') {
+ lastCardDom.style.width = '100px'
+ lastCardDom.style.border = 'none'
+ }
+
+ // use target's ID to find card object in array
+ let index = parseInt(event.target.getAttribute('id'))
+
+ // if value or color matches topOfPlayPile OR color = 'any'
+ if (playerHand[index].value === playPile[playPile.length - 1].value || playerHand[index].color === playPile[playPile.length - 1].color || playerHand[index].color === 'any' || playPile[playPile.length - 1].color === 'any') {
+
+ // animate clicked card
+ pickPlayCardSound()
+ event.target.classList.add('play-card')
+ console.log('you played', event.target) // TODO: remove
+
+ setTimeout(() => {
+ // set topOfPlayPile to target.src
+ //topOfPlayPile.length = 0
+ playPlayerCard(index)
+
+
+ // invoke cpuTurn to add cards if there are any to add
+ letCpuDrawCards()
+
+ // check playerHand length and update DOM
+ if (playerHand.length >= 1) {
+ updateHand(playerHand)
+ if (playerHand.length === 1) showUno(playerUno)
+ }
+ else {
+ updateHand(playerHand)
+ setTimeout(() => {
+ tallyPoints(cpuHand)
+ updateScores()
+ checkForWinner()
+ }, 1200)
+ }
+
+ //check if wild
+ if (playPile[playPile.length - 1].color === 'any' && playPile[playPile.length - 1].drawValue === 0 && playPile[playPile.length - 1].playedByPlayer) {
+ // set new color
+ showColorPicker()
+ return
+ }
+
+ skipOrEndTurn();
+ }, 1000)
+
+ }
+ }
+ })
+
+ let areYouSure = false
+
+ drawPileDom.addEventListener('click', () => {
+ if (playerTurn && !colorPickerIsOpen) {
+ drawCard(playerHand)
+ // playerTurn = false;
+ // setTimeout(playCPU, cpuDelay)
+ setTimeout(() => {
+ playerTurn = false;
+ setTimeout(playCPU, cpuDelay)
+ }, 500)
+ }
+ })
+}
+//#endregion
+let cpuVisible = false
+
+const listenForDevMode = () => {
+ document.addEventListener('keydown', event => {
+ const key = event.key.toLowerCase()
+ console.log(key)
+ if (key === 'p') {
+ playerTurn = true;
+ console.log('forced playerTurn', playerTurn)
+ }
+
+ if (key === 'c') {
+ drawCard(cpuHand)
+ updateHand(cpuHand)
+ }
+
+ if (key === 'x') {
+ playerHand.pop()
+ updateHand(playerHand)
+ }
+
+ if (key === 'z') {
+ cpuHand.pop()
+ updateHand(cpuHand)
+ }
+
+ if (key === 'w') {
+ const wild = new Card('any', 13, 50, true, 0, 'images/wild13.png')
+ playerHand.push(wild)
+ updateHand(playerHand)
+ }
+
+ if (key === '4') {
+ const wild4 = new Card('any', 14, 50, true, 4, 'images/wild14.png')
+ playerHand.push(wild4)
+ updateHand(playerHand)
+ }
+
+ if (key === '=') {
+ playerScore += 10
+ updateScores()
+ }
+
+ if (key === 's') {
+ if (cpuVisible) {
+ hideCpuCards()
+ cpuVisible = false
+ }
+ else {
+ showCpuCards()
+ cpuVisible = true
+ }
+ }
+ })
+}
+
+startGame()
diff --git a/UNO/play-here-uno.svg b/UNO/play-here-uno.svg
new file mode 100644
index 0000000..9ce43c9
--- /dev/null
+++ b/UNO/play-here-uno.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/UNO/uno-mockup.png b/UNO/uno-mockup.png
new file mode 100644
index 0000000..4ca199f
Binary files /dev/null and b/UNO/uno-mockup.png differ
diff --git a/index.html b/index.html
index d1cb876..3a5e002 100644
--- a/index.html
+++ b/index.html
@@ -560,6 +560,18 @@ Game
+
+
UNO
+
+
UNO
+
Game
+
Can You Defeat The Cpu ?
+
+ TRY NOW!
+
+
+
+