La Brava Logs:忍者主題剪刀石頭布遊戲
La Brava Logs: The Rock Paper Scissors SHINOBI GAME
作者把剪刀石頭布作業改造成忍者對戰主題遊戲,並以 Rokku、Kami、Hasami 分別代表石頭、布和剪刀。遊戲設計以瀏覽器點擊事件觸發回合,讓電腦隨機出招,先取得 5 分的一方獲勝,並設有背景音樂播放切換。
// ==========================================
/// The Rock paper scissors project
// ==========================================
<!This is my vision, and only mine-->
I am still trying to process everything I have done with this project. I am not in the place I should be, at least not physically. However, when I am inside the terminal everything just clicks! Until it does not... But, that is part of the thrill of doing something like this. Who needs a rollercoaster, when you can just code, and go through all kind of turns, and up and downs all by yourself like this??!!
I have gone through so much, and something inside me changed since I started this project. Once more, I went beyond what the assignment asked, and just did what felt right, and followed the itch, of what I felt like I had to do. I mean, why just follow a tutorial mindlessly, when you can create your own thing? Because otherwise it is just dull, and soulless, and what is the point of having something that does not make you feel anything? So, of course for this I also had to go beyond!
As I started writing this, I actually went back and forth, and made more tweaks, and perfected it even more, to ensure that every single thing falls into place the way it should. Because it is all about the itch, this primitive raw need to create something, something that was really something, something meaningful! When at first I read the preview of the assignment, I had this anxiety of not knowing what to expect or how it would go, so I had to also battle that. Then, after that, once I finally got there, and read back and forth many times the assignment, and many daydreams later, and more—Something came. It was once I reached step number 4:
“Step 4: Declare the players score variables
Your game will keep track of the players score. You will write variables to keep track of the players score.
Create two new variables named
humanScore and computerScore
in the global scope.
Initialize those variables with the value of 0”
I went back and read the whole assignment steps again, as I was trying to figure it out. Here in this very step, I had an epiphany! It all started when I was wondering why, and who made that up that paper beats rock, and how in my own version of the game that never happened! Just like a string of code, the rabbit hole of thought kept spiraling, as I kept visualizing how the hands move during this childish game. Then, it was here when it hit me! This game could not be a mundane regular rock paper scissors game! There is no way that even for something like this I could settle for something so ordinary!
The hand signs for the game made me to remember how the hands move when trying to make a hand sign for an attack in Naruto. Something like this did make a spark in me. This had to be the one. So, I started to delve in the first layer of the assignment, after finishing the lesson “Understanding Errors” I took my time to figure it all out, and breaking, redoing, deleting, and redoing until I got it right. All of this with the sole purpose to recreate a worthy shinobi battle, and transform it into something tangible, and part of the reality in this world.
As I am trying to write this article, I have realized that under no circumstances I should ever use again certain types of AI as a note dump of my thought process... Because now it says, because it was so long that the beginning of it is not around anymore, and only the most recent things… So, even more to learn from this.
Without further ado, I humbly welcome you to my latest creation:
1. Pseudo-code
PROGRAM ShinobiRockPaperScissors
// 1. SETUP & INITIALIZATION
Define choices = ["Rokku" (Rock), "Kami" (Paper), "Hasami" (Scissors)]
Set playerSelection = null
Set computerSelection = null
Set playerScore = 0
Set computerScore = 0
Set maxScore = 5
Set musicPlaying = false
// 2. AUDIO & UI EVENT HANDLING
WHEN user clicks Music Toggle Button OR interacts with the game:
IF music is paused:
Play "SIGN" background audio
Update music button text to "Music playing"
ELSE:
Pause background audio
Update music button text to "Music paused"
// 3. COMPUTER JUTSU GENERATION
FUNCTION getComputerChoice():
Generate random index between 0 and 2
Return choices[random index]
// 4. ROUND EVALUATION LOGIC
FUNCTION playRound(playerJutsu, computerJutsu):
IF playerScore >= maxScore OR computerScore >= maxScore:
RETURN // Freeze game if duel is already over
Display playerJutsu vs computerJutsu on battle cards
IF playerJutsu == computerJutsu:
Display "Draw! Both Shinobi used the same technique!"
ELSE IF (playerJutsu wins against computerJutsu):
// (Rokku beats Hasami | Kami beats Rokku | Hasami beats Kami)
Increment playerScore by 1
Display victory message for the round
ELSE:
Increment computerScore by 1
Display defeat message for the round
Update score displays on screen (playerScore, computerScore)
// Check for match outcome
CHECK_MATCH_OVER()
// 5. MATCH TERMINATION
FUNCTION CHECK_MATCH_OVER():
IF playerScore == maxScore:
Display "Victory! You have achieved the rank of Hokage!"
Disable attack buttons
ELSE IF computerScore == maxScore:
Display "Defeat! Your opponent outperformed your Ninpo!"
Disable attack buttons
// 6. MAIN EVENT LISTENERS
WHEN user clicks "Rock (Rokku)" button:
playRound("Rokku", getComputerChoice())
WHEN user clicks "Paper (Kami)" button:
playRound("Kami", getComputerChoice())
WHEN user clicks "Scissors (Hasami)" button:
playRound("Hasami", getComputerChoice())
END PROGRAM
2. Restructuring
Merged Core Logic with Narrative: Replaced generic terms (”rock”, “paper”, “scissors”) with themed Ninpo choices (Rokku, Kami, Hasami).
Planned Event-Driven Flow: Shifted from console loops (while / for) to browser event listeners (click), allowing user input to directly trigger single rounds.
Integrated Game State & Media: Outlined score tracking up to 5 points, win/loss freezing conditions, and dynamic audio playback handling within the core user interaction loop.
3. The First Execution
Created a new Git repository for the project.
Created a blank HTML document with a script tag linking an external JavaScript file to keep the HTML clean.
Verified that JavaScript was linked correctly by writing console.log("Hello World") and checking that it logged successfully in the browser console.
4. The Second Execution
Created a function named getComputerChoice.
Wrote code using Math.random() to conditionally and randomly return one of three string values: "rock", "paper", or "scissors".
Tested that the function returned the expected value using console.log and browser developer tools.
Human Choice Logic
Created a function named getHumanChoice.
Used the prompt method inside the function to capture user input and return a valid choice.
Tested the function’s return value using console.log.
Player Score Variables
Created two new variables named humanScore and computerScore in the global scope.
Initialized both variables with a starting value of 0.
Single Round Logic (playRound)
Created a function named playRound with two parameters: humanChoice and computerChoice.
Made the humanChoice parameter case-insensitive so players could input variations like "rock", "ROCK", or "RocK".
Wrote code inside playRound to console.log a string value representing the round winner (e.g., "You lose! Paper beats Rock").
Incremented either the humanScore or computerScore variable depending on who won the round.
Full Game Logic (playGame)
Created a function named playGame.
Moved the playRound function and score variables so they were declared inside the playGame function.
Played 5 rounds by calling playRound 5 times, kept track of the running scores, and declared an overall winner at the end.
I went along by the feeling of the moment. I felt like because of the nature of the game, that Naruto was the most fitting, and I also chose the song to play with it, SIGN, because of the hand signs done to play this game is a form of jutsu too, as it is needed to activate the attacks. Doing something like this has always been my dream, and thanks to The Odin Project, I got the tools, and starter points to make my dream reality. I will always be grateful for The Odin Project for making my dream come true! Thank you for everyone in The Odin Project!! After finishing this first module of the project, I inspected the page in dev tools, and fixed any possible errors, such as syntax errors to ensure that the game actually worked inside the console, redoing each time, until it was working the way I imagined it to be.
After this initial stage, I continued with the following lessons, and putting this on hold, as the assignment said, because to move forward I had to complete the next lessons. I did not follow the recommendations of just doing something generic, because I had to experiment with this no matter what, or else I would never know how it is like.
5. Revisiting the Rock Paper Scissors Project
After moving on with the lessons, the reading material, lectures, and directed a self-made project to satisfy my curiosity, and inner critic, as the article LaBrava Logs: The Learn Git Branching JS, once I was ready, I went back to the Rock Paper Scissors project. It was time to transition getting the game out of the Javascript console, and bring it outside of it. At first, it was a regular basic html website, and throughout most of the project was only hosted locally, until I pushed it live. I am a perfectionist, and I do not do things half-heartedly. I had to ensure that my game was exactly as I imagined it to be. So, I proceeded to follow my vision. What followed in the project was:
Connecting the DOM & Managing State
Initialized tracking variables (humanScore = 0, computerScore = 0, winningScore = 5) to manage game state directly within the web page.
Selected DOM elements using document.querySelector (such as #human-score, #computer-score, #round-result, and choice display cards) to establish a bridge between JavaScript state and UI elements.
Upgrading Choice Logic & Event Listeners
Updated the getComputerChoice() function using an array of choices (["rock", "paper", "scissors"]) combined with Math.random() and Math.floor() to select array indices cleanly.
Grabbed the UI buttons (#rock, #paper, #scissors) and attached click event listeners (addEventListener("click", ...)) to trigger playRound() directly from user clicks on the page.
Dynamic UI Updates & Round Logic
Refactored playRound() to evaluate human vs. computer choices using compound boolean conditions (&&, ||) while updating live text content (textContent) for scores and round outcomes in real-time.
Applied .toLowerCase() on inputs to maintain case-insensitivity across logic checks.
Implemented game-state freezing so that once either the player or computer reaches 5 points, further button clicks are safely ignored to preserve the final outcome.
Overcoming Browser Autoplay Policies & Audio Syncing
Integrated the backgroundMusic audio element (”SIGN” by FLOW) set to a 30% volume level.
Handled modern browser autoplay restrictions by implementing asynchronous Promise handling (.then().catch()), triggering .play() on the player’s first interaction or via the dedicated toggle button.
Synchronized the UI state of the audio button to dynamically reflect whether music was active or paused.
Version Control, Transparency, and Deployment
Updated README.md to document open-source transparency: providing attribution for the audio track by FLOW and explicitly noting that the background art serves as an AI-generated placeholder.
Used Git to track changes across files (index.html, style.css, script.js, README.md), committed progress with clear messages, pushed to main, and deployed the live site through GitHub Pages.
In other words, I went beyond what the project asked, and I learned even more beyond what the curriculum assigned, and how to download more things in the terminal, and go through all the hurdles to get the music, make the music be present, and playable once the user interacts with the retro style arcade game that I created. I did not just follow the tutorial assignment, I went beyond, feeling the project to the fullest, as if it was the last thing I could do. As I am still figuring out how to make proper technical articles (more used to creative writing, but I have always dreamed of doing this too!), I did my best to explain the structure breakdown, and a summary of my journey and of what I did. From fighting syntax errors, and so lost in the moment, that at times I even made duplicate declarations, without even noticing! To going all the way to the production, and making my game to be playable outside a local host, and bringing it to life fully. Fighting sleep deprivation, illnesses, and an unstable external environment to make this work. Moreover, it was also letting the global reference handle scope across the entire application lifecycle, rewriting the game as many times as possible until it reached the version that it had to be, its true version. From:
“function playRound(humanChoice, computerChoice) {
// your code here!
}
const humanSelection = getHumanChoice();
const computerSelection = getComputerChoice();
playRound(humanSelection, computerSelection);”
To what has become, it has truly transformed into a truly shinobi experience!
Acknowledgments & Foundations
This project could not have come to life as it is now, had it not been for The Odin Project. Therefore, I dedicate this article, and my entire project in their honor. I owe this to them, even if they do not know me. I could not feel any more grateful towards the open-source creators, maintainers, and community contributors of TOP for providing the step-by-step roadmap that guided the transition from raw JavaScript syntax and console logic to clean, modular DOM manipulation and event-driven architecture. It gave me the chance to make one of my dreams I always had, to make it come true.
I transformed the assigned project, and transformed it into something of my very own. If some Naruto fan ever sees this, I hope it is a good enough rock paper scissors fan-made game for them too! I did this all by myself. I do not know what will happen after this, but I am glad I could make this happen. From JavaScript syntax, and console isolated logic, to modular DOM manipulation, and event-driven architecture. Now, I am just not a dreamer, I am a doer, and it is all thanks to The Odin Project to guide me towards this! Thank you so much for this, and thank you dear reader, for joining me in this journey.
If you wish to play the game, it is here: https://labravacodes-dot.github.io/Rock-paper-scissors/
來源:DEV Community · dev.to