diff --git a/.config/configstore/update-notifier-pnpm.json b/.config/configstore/update-notifier-pnpm.json new file mode 100644 index 00000000..b8d6c2ec --- /dev/null +++ b/.config/configstore/update-notifier-pnpm.json @@ -0,0 +1,4 @@ +{ + "optOut": false, + "lastUpdateCheck": 1567913417343 +} \ No newline at end of file diff --git a/.config/glitch-package-manager b/.config/glitch-package-manager new file mode 100644 index 00000000..adcdaede --- /dev/null +++ b/.config/glitch-package-manager @@ -0,0 +1 @@ +pnpm diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/.glitch-assets b/.glitch-assets new file mode 100644 index 00000000..e69de29b diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 304a16f1..fdde6ef9 --- a/README.md +++ b/README.md @@ -1,89 +1,24 @@ -Assignment 2 - Short Stack: Basic Two-tier Web Application using HTML/CSS/JS and Node.js -=== +Mastermind -Due: September 9th, by 11:59 AM. +An HTML implementation of the board of the same name. +The player must guess the correct combination of colored balls in order to win. +Each time the player guesses, the server will respond by telling the player how many balls are of the +right color and the right position, as well how many are of the right color but in the wrong position. +This information then allows the player to make increasingly educated guesses until the answer is found. -This assignment aims to introduce you to the concepts and practice involved in creating a prototype (i.e. not deployment ready) two-tiered web application. +Although the webpage deosn't seem to do anything in response, they can actually be found in the incoming packets. +On Chrome, these can be found in the developer tools, on the 'Network' tab. -The baseline aims of this assignment involve creating an application that demonstrates the use of several specific pieces of HTML, CSS, JavaScript, and Node.js functionality. -Another aim of this assignment is to establish creative boundaries in which you and your partner can explore designing, implementing, and evaluating usable, useful, novel, and technically efficient web applications. +On winning the game, the server will respond by dumping the data stored in the server, including the player's name, +the number of moves in which they won, and the medal awarded to their score. -Baseline Requirements ---- +Every time the page is entered, a new board will be generated. This allows the player to start a new game by refreshing the page, +but also means only one person can play at any given time. -Note that there is a very large range of application areas and possibilities that meet these baseline requirements. -Games, internet of things, organizational tools, commerce, media - all are possibilities with a two-tiered form-focused web application. - -Do not limit yourselves to any of the examples given below. -Examples like the upcoming `efficiency_ratio` idea for the `cars` dataset are meant to be illustrative and easy to understand. -They are not intended to be sensible or useful ideas. - -Your application is required to implement the following functionalities: - -- a `Server` which not only serves files, but also maintains a tabular dataset with 3 or more fields related to your application -- a `Results` functionality which shows the entire dataset residing in the server's memory -- a `Form/Entry` functionality which allows a user to add, modify, or delete data items residing in the server's memory -- a `Server Logic` which, upon receiving new or modified "incoming" data, includes and uses a function that adds at least one additional derived field to this incoming data before integrating it with the existing dataset - - the `Derived field` for a new row of data must be computed based on fields already existing in the row. For example, a `cars` dataset with `year`, `horsepower`, and `fuel_efficiency` may create a new field `efficiency_ratio` by dividing `fuel_efficiency` by `horsepower` - -Your application is required to demonstrate the use of the following concepts: - -HTML: -- One or more [HTML Forms](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms), with any combination of form tags appropriate for the user input portion of the application - - Clarification: the results page can be implemented in any way. `
`s, `table`s, and `list`s are common choices - -CSS: -- CSS styling of the primary visual elements in the application -- Various CSS Selector functionality must be demonstrated: - - Element selectors - - ID selectors - - Class selectors -- CSS positioning and sizing of the primary visual elements in the application: - - CSS to cause at least one element to be horizontally centered on the page - - CSS to cause at least one pair of elements to appear side-by-side - - CSS defined in a maintainable, readable form, in external stylesheets - -JavaScript: -- At minimum, a small amount of front-end JavaScript to get / fetch data from the server; a sample is provided in this repository. - -Node.js: -- An HTTP Server that delivers all necessary files and data for the application. A starting point is provided in this repository. - -Deliverables ---- - -Do the following to complete this assignment: - -1. Fork the starting project code. This repo contains some starter code that may be used or discarded as needed. -2. Implement your project with the above requirements. -3. Test your project to make sure that when someone goes to your main page, it displays correctly. -4. Deploy your project to Glitch, and fill in the appropriate fields in your package.json file. -5. Ensure that your project has the proper naming scheme `a2-yourname` so we can find it. -6. Modify the Readme to the specifications below. -7. Create and submit a Pull Request to the original repo. Label the pull request as follows: a2-gitusername-firstname-lastname - -Sample Readme (delete the above when you're ready to submit, and modify the below so with your links and descriptions) ---- - -## Your Web Application Title -Include a very brief summary of your project here. -Images are encouraged, along with concise, high-level text. - -Here is a sample formula for summarizing your activities, talk about: -- the domain area the project pertains to -- the main challenges or problems the application addresses -- the key innovations that make it possible to address the problem -- the main results of the implementation, does it really address the problem? -- any additional implications of the resulting application, or possibly areas for future work that have been discovered as part of the design and implementation activities - -(Note that when I use the above formula, I aim to have only one sentence per thought in order to remain concise.) - -http://a2-charlieroberts.glitch.me +Glitch App: https://a2-javiermarcos.glitch.me ## Technical Achievements -- **Tech Achievement 1**: Using a combination of... -- **Tech Achievement 2**: ... +- **Tech Achievement 1**: Made a back and forth between server and client and having the server react to the provided information ### Design/Evaluation Achievements -- **Design Achievement 1**: Shown in `style.css`, the code... -- **Design Achievement 2**: We tested the application with n=X users, finding that... +- **Design Achievement 1**: Introduced a few new fonts and some minor styling of the page. diff --git a/package.json b/package.json old mode 100755 new mode 100644 diff --git a/public/css/style.css b/public/css/style.css old mode 100755 new mode 100644 index d5f842ab..2db51678 --- a/public/css/style.css +++ b/public/css/style.css @@ -1 +1,23 @@ -/*Style your own assignment! This is fun! */ \ No newline at end of file +@import url('https://fonts.googleapis.com/css?family=Noto+Serif|Righteous&display=swap'); + +body { + font-family: 'Noto Serif', serif; + background-color: #DBE0C5; +} + +h1 { + font-family: 'Righteous', cursive; + font-size: 68px; + text-align: center; +} + +h2 { + font-family: 'Righteous', cursive; +} + +#instructions { + font-size: 16px; +} + +#guess { +} \ No newline at end of file diff --git a/public/index.html b/public/index.html old mode 100755 new mode 100644 index c56d620e..4216a700 --- a/public/index.html +++ b/public/index.html @@ -3,39 +3,117 @@ CS4241 Assignment 2 + -
- - -
+

Mastermind

+
+ There is a secret code, made up of a random combination of 4 balls with 6 possible colors each.
+ You must try to find the correct combination with as few guesses as you can.
+ Each time you guess you will be told how many of the balls in your proposed soultion are: + + Think carefully! If you fail to crack the code by your 15th guess, you lose! +
+
+

Name:

+ +
+
+
+

Take a guess!

+ First Ball + +
+ + Second Ball + +
+ + Third Ball + +
+ + Fourth Ball + +
+ + +
+
+ diff --git a/public/js/scripts.js b/public/js/scripts.js old mode 100755 new mode 100644 diff --git a/server.improved.js b/server.improved.js index 26673fc0..e5287d97 100644 --- a/server.improved.js +++ b/server.improved.js @@ -6,15 +6,13 @@ const http = require( 'http' ), dir = 'public/', port = 3000 -const appdata = [ - { 'model': 'toyota', 'year': 1999, 'mpg': 23 }, - { 'model': 'honda', 'year': 2004, 'mpg': 30 }, - { 'model': 'ford', 'year': 1987, 'mpg': 14} +var playerData = [ + {'name': "Javier", 'moves': 0, 'medal': "platinum"} ] const server = http.createServer( function( request,response ) { if( request.method === 'GET' ) { - handleGet( request, response ) + handleGet( request, response ) }else if( request.method === 'POST' ){ handlePost( request, response ) } @@ -24,6 +22,9 @@ const handleGet = function( request, response ) { const filename = dir + request.url.slice( 1 ) if( request.url === '/' ) { + // If page is entered or refreshed, generate a new board + generateBoard() + console.log(board) sendFile( response, 'public/index.html' ) }else{ sendFile( response, filename ) @@ -38,12 +39,50 @@ const handlePost = function( request, response ) { }) request.on( 'end', function() { - console.log( JSON.parse( dataString ) ) - - // ... do something with the data here!!! - - response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) - response.end() + var obj = JSON.parse( dataString ) + + // Turn player response into an 4 digit array + var playerGuess = extractAnswer(obj) + console.log(playerGuess) + + // Check if data is valid + for (var i = 0; i < 4; i++) { + if (playerGuess[i] == -1) { + response.writeHead( 400, "Bad response", {'Content-Type': 'text/plain' }) + response.end() + } + } + + // If valid, check against solution + var color = rightColor(playerGuess) + var colorNpos = rightPosition(playerGuess) + + if (colorNpos == 4 && obj.guesscount <= 15) { + var medal = giveMedal(obj.guesscount) + var newEntry = { 'name': obj.playername, + 'moves': obj.guesscount, + 'medal': giveMedal(obj.guesscount)} + playerData.push(newEntry) + + + response.writeHead(200, "OK", { 'Content-Type': 'text/plain' }) + //response.end("You got a " + medal + " medal!") + response.end(JSON.stringify(playerData)) + } + + else if (obj.guesscount == 15) { + response.writeHead(200, "OK", { 'Content-Type': 'text/plain' }) + response.end("You lost!") + } + + else { + var clues = {'color': color, + 'colornpos': colorNpos} + var cbody = JSON.stringify(clues) + + response.writeHead(200, "OK", { 'Content-Type': 'text/plain' }) + response.end(cbody) + } }) } @@ -69,4 +108,73 @@ const sendFile = function( response, filename ) { }) } +var board = [-1, -1, -1, -1] + +// Create a random array of 4 numbers, each from 0 to 5 +const generateBoard = function() { + for (var i = 0; i < 4; i++) { + board[i] = Math.floor(6 * Math.random()) + } + return board +} + +// Extract the user's answer +const extractAnswer = function(json) { + var answer = [colorToNumber(json.firstball), + colorToNumber(json.secondball), + colorToNumber(json.thirdball), + colorToNumber(json.fourthball)] + return answer +} + +// Translates each answer from a string to a number +const colorToNumber = function(color) { + if (color == "red") { return 0 } + else if(color == "blue") { return 1 } + else if(color == "yellow") { return 2 } + else if(color == "green") { return 3 } + else if(color == "purple") { return 4 } + else if(color == "orange") { return 5 } + else { return -1 } +} + +// Returns the number of ball of the right color, regardless of position +const rightColor = function(pGuess) { + var solTally = [0, 0, 0, 0, 0, 0] + for (var s = 0; s < 6; s++) { + for (var b = 0; b < 4; b++) { + if (board[b] == s) { solTally[s]++ } + } + } + + var guessTally = [0, 0, 0, 0, 0, 0] + for (var s = 0; s < 6; s++) { + for (var b = 0; b < 4; b++) { + if (pGuess[b] == s) { guessTally[s]++ } + } + } + + var correctColor = 0 + for (var s = 0; s < 6; s++) { + correctColor = correctColor + Math.min(solTally[s], guessTally[s]) + } + + return correctColor +} + +const rightPosition = function(pGuess) { + var correctPos = 0; + for (var j = 0; j < 4; j++) { + if (board[j] == pGuess[j]) { correctPos++ } + } + return correctPos +} + +const giveMedal = function(guessCount) { + if (guessCount <= 6) { return "platinum" } + else if (guessCount <= 8) { return "gold" } + else if (guessCount <= 12) { return "silver" } + else { return "bronze" } +} + server.listen( process.env.PORT || port ) diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml new file mode 100644 index 00000000..86c7048d --- /dev/null +++ b/shrinkwrap.yaml @@ -0,0 +1,15 @@ +dependencies: + mime: 2.4.4 +packages: + /mime/2.4.4: + dev: false + engines: + node: '>=4.0.0' + hasBin: true + resolution: + integrity: sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== +registry: 'https://registry.npmjs.org/' +shrinkwrapMinorVersion: 9 +shrinkwrapVersion: 3 +specifiers: + mime: ^2.4.4