├── .vs ├── ProjectSettings.json └── slnx.sqlite ├── screenshots ├── ingame.jpg ├── youdied.png └── startscreen.png ├── main.asm ├── main.asm │ ├── main.asm.vcxproj.filters │ ├── main.asm.vcxproj │ └── main.asm └── main.asm.sln ├── LICENSE ├── .gitattributes ├── README.md └── .gitignore /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/.vs/slnx.sqlite -------------------------------------------------------------------------------- /screenshots/ingame.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/ingame.jpg -------------------------------------------------------------------------------- /screenshots/youdied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/youdied.png -------------------------------------------------------------------------------- /screenshots/startscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/startscreen.png -------------------------------------------------------------------------------- /main.asm/main.asm/main.asm.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 meixinchoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /main.asm/main.asm.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1209 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "main.asm", "main.asm\main.asm.vcxproj", "{EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x64.ActiveCfg = Debug|x64 17 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x64.Build.0 = Debug|x64 18 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x86.ActiveCfg = Debug|Win32 19 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x86.Build.0 = Debug|Win32 20 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x64.ActiveCfg = Release|x64 21 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x64.Build.0 = Release|x64 22 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x86.ActiveCfg = Release|Win32 23 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {1EE34913-FC21-43DC-A88E-DC625C27180E} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Assembly Language Snake Game 2 | ## About the project 3 | This program is a personal project when I was learning 'computer organization and architecture' in the second year of my Management Mathematics and Computing bachelors degree. The idea behind of this program was the classic "Snake" game. This program was made using Microsoft Visual Studio 2017's 32bit MASM architecture in protected mode (no interrupts) and the Irvine32 library. 4 | 5 | ## Features and Functions 6 | #### Game Speed Selection 7 | * User may choose from three speed levels, level 1 to level 3, level 3 being the slowest. 8 | * Each of the speed levels have a 40ms difference. 9 | #### Random Generation of coin 10 | * A coin is generated randomly at the start of every game or when the snake eats the previous coin. 11 | * A checking function is also created to make sure that the random coin doesnt generate on the coordinates of the snake. 12 | * A new coin is regenerated if the current one is generated at an invalid coordinate. 13 | #### Accepting keyboard input 14 | * After the coin is generated, a loop will be initiated to detect for input and jump to specific functions according to the input. 15 | * If no key is entered, the program will keep looping and waiting for an input. 16 | * If the snake is moving and a valid input is not entered, the function will continuously loop and snake will continuous to move at the current direction. 17 | * If the user enters a new input that moves the snake in a different direction, the program will jump to a function that changes the function of the snake. 18 | #### Move Snake 19 | * The head of the snake will be moved according to the user's last known input. 20 | * The body of the snake will be moved to the coordinate of the unit before it (eg: the 3rd unit of the body will move to the coordinates of the 2nd unit of the body) 21 | #### Coin Detection 22 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake eats a coin 23 | #### Eat Coin 24 | * When a coin is eaten, a new unit is added to the snake to lengthen the snake. 25 | * The new tail is at the position of the old tail, a new tail is added according to the direction of the old tail 26 | #### Self Collision Detection 27 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake collides with itself 28 | * Snake dies when it collides with itself 29 | * A function loops through the coordinates of the body of the snake and compares with the head position to check if they collide. 30 | #### Wall Collision Detection 31 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake collides with the wall 32 | * Snake dies when it collides with the wall 33 | * A function compares the coordinates of the wall and the head to check if they collide 34 | #### Scoreboard 35 | * When the game is over, a scoreboard is displayed to show the current score and high score of the user. 36 | * The user can also choose to exit the game or restart the game. 37 | #### Input Validation 38 | * Input Validation is set to detect any invalid input and prompts the user to reenter the input if so. 39 | 40 | ## Flowchart 41 | Flowchart of this program can be downloaded here: [snake game flowchart.pdf](https://github.com/meixinchoy/SnakeGame-asm8086/files/6953798/snake.game.flowchart.pdf) 42 | 43 | ## Controls 44 | | Keys | Actions | 45 | | ----------------- | --------------------------- | 46 | | w | Move up | 47 | | a | Move left | 48 | | s | Move down | 49 | | d | Move right | 50 | | x | Quits the game at any time | 51 | | enter | Pause, (w,a,s,d to unpause) | 52 | 53 | (make sure that your capslock is disabled) 54 | 55 | ## Screenshots 56 | ![](screenshots/startscreen.png) 57 | 58 | ![](screenshots/ingame.jpg) 59 | 60 | ![](screenshots/youdied.png) 61 | 62 | ## Installation 63 | To start the game you will need to install the following items: 64 | 1. visual studios (can be installed [here](https://visualstudio.microsoft.com/downloads/)) 65 | 2. Irvine32 library (can be downloaded [here](https://github.com/meixinchoy/Irvine-library)) 66 | 3. configure asm file, paste code in and run program 67 | 68 | ## Additional Notes 69 | Although the program code for the master branch and the adv branch slightly differs from each other, both codes are completed and able to output and run the full program. The master branch is more basic and easier to understand whereas the code in the develop branch more compact and the end screen displays the high score as well. Feel free to check out both versions of my program. 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /main.asm/main.asm/main.asm.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {ec2c0af4-6d7e-401b-8e6c-534cb2a28945} 24 | main_asm 25 | 10.0.17763.0 26 | main.asm 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | MultiByte 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | MultiByte 41 | 42 | 43 | Application 44 | true 45 | v141 46 | MultiByte 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | MultiByte 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | Level3 78 | Disabled 79 | true 80 | true 81 | 82 | 83 | Console 84 | c:\Irvine 85 | Irvine32.lib;%(AdditionalDependencies) 86 | 87 | 88 | c:\Irvine 89 | 90 | 91 | 92 | 93 | Level3 94 | Disabled 95 | true 96 | true 97 | 98 | 99 | Console 100 | 101 | 102 | 103 | 104 | Level3 105 | MaxSpeed 106 | true 107 | true 108 | true 109 | true 110 | 111 | 112 | Console 113 | true 114 | true 115 | 116 | 117 | 118 | 119 | Level3 120 | MaxSpeed 121 | true 122 | true 123 | true 124 | true 125 | 126 | 127 | Console 128 | true 129 | true 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /main.asm/main.asm/main.asm: -------------------------------------------------------------------------------- 1 | .386 2 | .model flat, stdcall 3 | .stack 4096 4 | ExitProcess PROTO, dwExitCode: DWORD 5 | INCLUDE Irvine32.inc 6 | 7 | .data 8 | 9 | xWall BYTE 52 DUP("#"),0 10 | 11 | strScore BYTE "Your score is: ",0 12 | score BYTE 0 13 | 14 | strTryAgain BYTE "Try Again? 1=yes, 0=no",0 15 | invalidInput BYTE "invalid input",0 16 | strYouDied BYTE "you died ",0 17 | strPoints BYTE " point(s)",0 18 | blank BYTE " ",0 19 | 20 | snake BYTE "X", 104 DUP("x") 21 | 22 | xPos BYTE 45,44,43,42,41, 100 DUP(?) 23 | yPos BYTE 15,15,15,15,15, 100 DUP(?) 24 | 25 | xPosWall BYTE 34,34,85,85 ;position of upperLeft, lowerLeft, upperRight, lowerRignt wall 26 | yPosWall BYTE 5,24,5,24 27 | 28 | xCoinPos BYTE ? 29 | yCoinPos BYTE ? 30 | 31 | inputChar BYTE "+" ; + denotes the start of the game 32 | lastInputChar BYTE ? 33 | 34 | strSpeed BYTE "Speed (1-fast, 2-medium, 3-slow): ",0 35 | speed DWORD 0 36 | 37 | .code 38 | main PROC 39 | call DrawWall ;draw walls 40 | call DrawScoreboard ;draw scoreboard 41 | call ChooseSpeed ;let player to choose Speed 42 | 43 | mov esi,0 44 | mov ecx,5 45 | drawSnake: 46 | call DrawPlayer ;draw snake(start with 5 units) 47 | inc esi 48 | loop drawSnake 49 | 50 | call Randomize 51 | call CreateRandomCoin 52 | call DrawCoin ;set up finish 53 | 54 | gameLoop:: 55 | mov dl,106 ;move cursor to coordinates 56 | mov dh,1 57 | call Gotoxy 58 | 59 | ; get user key input 60 | call ReadKey 61 | jz noKey ;jump if no key is entered 62 | processInput: 63 | mov bl, inputChar 64 | mov lastInputChar, bl 65 | mov inputChar,al ;assign variables 66 | 67 | noKey: 68 | cmp inputChar,"x" 69 | je exitgame ;exit game if user input x 70 | 71 | cmp inputChar,"w" 72 | je checkTop 73 | 74 | cmp inputChar,"s" 75 | je checkBottom 76 | 77 | cmp inputChar,"a" 78 | je checkLeft 79 | 80 | cmp inputChar,"d" 81 | je checkRight 82 | jne gameLoop ; reloop if no meaningful key was entered 83 | 84 | 85 | ; check whether can continue moving 86 | checkBottom: 87 | cmp lastInputChar, "w" 88 | je dontChgDirection ;cant go down immediately after going up 89 | mov cl, yPosWall[1] 90 | dec cl ;one unit ubove the y-coordinate of the lower bound 91 | cmp yPos[0],cl 92 | jl moveDown 93 | je died ;die if crash into the wall 94 | 95 | checkLeft: 96 | cmp lastInputChar, "+" ;check whether its the start of the game 97 | je dontGoLeft 98 | cmp lastInputChar, "d" 99 | je dontChgDirection 100 | mov cl, xPosWall[0] 101 | inc cl 102 | cmp xPos[0],cl 103 | jg moveLeft 104 | je died ; check for left 105 | 106 | checkRight: 107 | cmp lastInputChar, "a" 108 | je dontChgDirection 109 | mov cl, xPosWall[2] 110 | dec cl 111 | cmp xPos[0],cl 112 | jl moveRight 113 | je died ; check for right 114 | 115 | checkTop: 116 | cmp lastInputChar, "s" 117 | je dontChgDirection 118 | mov cl, yPosWall[0] 119 | inc cl 120 | cmp yPos,cl 121 | jg moveUp 122 | je died ; check for up 123 | 124 | moveUp: 125 | mov eax, speed ;slow down the moving 126 | add eax, speed 127 | call delay 128 | mov esi, 0 ;index 0(snake head) 129 | call UpdatePlayer 130 | mov ah, yPos[esi] 131 | mov al, xPos[esi] ;alah stores the pos of the snake's next unit 132 | dec yPos[esi] ;move the head up 133 | call DrawPlayer 134 | call DrawBody 135 | call CheckSnake 136 | 137 | 138 | moveDown: ;move down 139 | mov eax, speed 140 | add eax, speed 141 | call delay 142 | mov esi, 0 143 | call UpdatePlayer 144 | mov ah, yPos[esi] 145 | mov al, xPos[esi] 146 | inc yPos[esi] 147 | call DrawPlayer 148 | call DrawBody 149 | call CheckSnake 150 | 151 | 152 | moveLeft: ;move left 153 | mov eax, speed 154 | call delay 155 | mov esi, 0 156 | call UpdatePlayer 157 | mov ah, yPos[esi] 158 | mov al, xPos[esi] 159 | dec xPos[esi] 160 | call DrawPlayer 161 | call DrawBody 162 | call CheckSnake 163 | 164 | 165 | moveRight: ;move right 166 | mov eax, speed 167 | call delay 168 | mov esi, 0 169 | call UpdatePlayer 170 | mov ah, yPos[esi] 171 | mov al, xPos[esi] 172 | inc xPos[esi] 173 | call DrawPlayer 174 | call DrawBody 175 | call CheckSnake 176 | 177 | ; getting points 178 | checkcoin:: 179 | mov esi,0 180 | mov bl,xPos[0] 181 | cmp bl,xCoinPos 182 | jne gameloop ;reloop if snake is not intersecting with coin 183 | mov bl,yPos[0] 184 | cmp bl,yCoinPos 185 | jne gameloop ;reloop if snake is not intersecting with coin 186 | 187 | call EatingCoin ;call to update score, append snake and generate new coin 188 | 189 | jmp gameLoop ;reiterate the gameloop 190 | 191 | 192 | dontChgDirection: ;dont allow user to change direction 193 | mov inputChar, bl ;set current inputChar as previous 194 | jmp noKey ;jump back to continue moving the same direction 195 | 196 | dontGoLeft: ;forbids the snake to go left at the begining of the game 197 | mov inputChar, "+" ;set current inputChar as "+" 198 | jmp gameLoop ;restart the game loop 199 | 200 | died:: 201 | call YouDied 202 | 203 | playagn:: 204 | call ReinitializeGame ;reinitialise everything 205 | 206 | exitgame:: 207 | exit 208 | INVOKE ExitProcess,0 209 | main ENDP 210 | 211 | 212 | DrawWall PROC ;procedure to draw wall 213 | mov dl,xPosWall[0] 214 | mov dh,yPosWall[0] 215 | call Gotoxy 216 | mov edx,OFFSET xWall 217 | call WriteString ;draw upper wall 218 | 219 | mov dl,xPosWall[1] 220 | mov dh,yPosWall[1] 221 | call Gotoxy 222 | mov edx,OFFSET xWall 223 | call WriteString ;draw lower wall 224 | 225 | mov dl, xPosWall[2] 226 | mov dh, yPosWall[2] 227 | mov eax,"#" 228 | inc yPosWall[3] 229 | L11: 230 | call Gotoxy 231 | call WriteChar 232 | inc dh 233 | cmp dh, yPosWall[3] ;draw right wall 234 | jl L11 235 | 236 | mov dl, xPosWall[0] 237 | mov dh, yPosWall[0] 238 | mov eax,"#" 239 | L12: 240 | call Gotoxy 241 | call WriteChar 242 | inc dh 243 | cmp dh, yPosWall[3] ;draw left wall 244 | jl L12 245 | ret 246 | DrawWall ENDP 247 | 248 | 249 | DrawScoreboard PROC ;procedure to draw scoreboard 250 | mov dl,2 251 | mov dh,1 252 | call Gotoxy 253 | mov edx,OFFSET strScore ;print string that indicates score 254 | call WriteString 255 | mov eax,"0" 256 | call WriteChar ;scoreboard starts with 0 257 | ret 258 | DrawScoreboard ENDP 259 | 260 | 261 | ChooseSpeed PROC ;procedure for player to choose speed 262 | mov edx,0 263 | mov dl,71 264 | mov dh,1 265 | call Gotoxy 266 | mov edx,OFFSET strSpeed ; prompt to enter integers (1,2,3) 267 | call WriteString 268 | mov esi, 40 ; milisecond difference per speed level 269 | mov eax,0 270 | call readInt 271 | cmp ax,1 ;input validation 272 | jl invalidspeed 273 | cmp ax, 3 274 | jg invalidspeed 275 | mul esi 276 | mov speed, eax ;assign speed variable in mililiseconds 277 | ret 278 | 279 | invalidspeed: ;jump here if user entered an invalid number 280 | mov dl,105 281 | mov dh,1 282 | call Gotoxy 283 | mov edx, OFFSET invalidInput ;print error message 284 | call WriteString 285 | mov ax, 1500 286 | call delay 287 | mov dl,105 288 | mov dh,1 289 | call Gotoxy 290 | mov edx, OFFSET blank ;erase error message after 1.5 secs of delay 291 | call writeString 292 | call ChooseSpeed ;call procedure for user to choose again 293 | ret 294 | ChooseSpeed ENDP 295 | 296 | DrawPlayer PROC ; draw player at (xPos,yPos) 297 | mov dl,xPos[esi] 298 | mov dh,yPos[esi] 299 | call Gotoxy 300 | mov dl, al ;temporarily save al in dl 301 | mov al, snake[esi] 302 | call WriteChar 303 | mov al, dl 304 | ret 305 | DrawPlayer ENDP 306 | 307 | UpdatePlayer PROC ; erase player at (xPos,yPos) 308 | mov dl, xPos[esi] 309 | mov dh,yPos[esi] 310 | call Gotoxy 311 | mov dl, al ;temporarily save al in dl 312 | mov al, " " 313 | call WriteChar 314 | mov al, dl 315 | ret 316 | UpdatePlayer ENDP 317 | 318 | DrawCoin PROC ;procedure to draw coin 319 | mov eax,yellow (yellow * 16) 320 | call SetTextColor ;set color to yellow for coin 321 | mov dl,xCoinPos 322 | mov dh,yCoinPos 323 | call Gotoxy 324 | mov al,"X" 325 | call WriteChar 326 | mov eax,white (black * 16) ;reset color to black and white 327 | call SetTextColor 328 | ret 329 | DrawCoin ENDP 330 | 331 | CreateRandomCoin PROC ;procedure to create a random coin 332 | mov eax,49 333 | call RandomRange ;0-49 334 | add eax, 35 ;35-84 335 | mov xCoinPos,al 336 | mov eax,17 337 | call RandomRange ;0-17 338 | add eax, 6 ;6-23 339 | mov yCoinPos,al 340 | 341 | mov ecx, 5 342 | add cl, score ;loop number of snake unit 343 | mov esi, 0 344 | checkCoinXPos: 345 | movzx eax, xCoinPos 346 | cmp al, xPos[esi] 347 | je checkCoinYPos ;jump if xPos of snake at esi = xPos of coin 348 | continueloop: 349 | inc esi 350 | loop checkCoinXPos 351 | ret ; return when coin is not on snake 352 | checkCoinYPos: 353 | movzx eax, yCoinPos 354 | cmp al, yPos[esi] 355 | jne continueloop ; jump back to continue loop if yPos of snake at esi != yPos of coin 356 | call CreateRandomCoin ; coin generated on snake, calling function again to create another set of coordinates 357 | CreateRandomCoin ENDP 358 | 359 | CheckSnake PROC ;check whether the snake head collides w its body 360 | mov al, xPos[0] 361 | mov ah, yPos[0] 362 | mov esi,4 ;start checking from index 4(5th unit) 363 | mov ecx,1 364 | add cl,score 365 | checkXposition: 366 | cmp xPos[esi], al ;check if xpos same ornot 367 | je XposSame 368 | contloop: 369 | inc esi 370 | loop checkXposition 371 | jmp checkcoin 372 | XposSame: ; if xpos same, check for ypos 373 | cmp yPos[esi], ah 374 | je died ;if collides, snake dies 375 | jmp contloop 376 | 377 | CheckSnake ENDP 378 | 379 | DrawBody PROC ;procedure to print body of the snake 380 | mov ecx, 4 381 | add cl, score ;number of iterations to print the snake body n tail 382 | printbodyloop: 383 | inc esi ;loop to print remaining units of snake 384 | call UpdatePlayer 385 | mov dl, xPos[esi] 386 | mov dh, yPos[esi] ;dldh temporarily stores the current pos of the unit 387 | mov yPos[esi], ah 388 | mov xPos[esi], al ;assign new position to the unit 389 | mov al, dl 390 | mov ah,dh ;move the current position back into alah 391 | call DrawPlayer 392 | cmp esi, ecx 393 | jl printbodyloop 394 | ret 395 | DrawBody ENDP 396 | 397 | EatingCoin PROC 398 | ; snake is eating coin 399 | inc score 400 | mov ebx,4 401 | add bl, score 402 | mov esi, ebx 403 | mov ah, yPos[esi-1] 404 | mov al, xPos[esi-1] 405 | mov xPos[esi], al ;add one unit to the snake 406 | mov yPos[esi], ah ;pos of new tail = pos of old tail 407 | 408 | cmp xPos[esi-2], al ;check if the old tail and the unit before is on the yAxis 409 | jne checky ;jump if not on the yAxis 410 | 411 | cmp yPos[esi-2], ah ;check if the new tail should be above or below of the old tail 412 | jl incy 413 | jg decy 414 | incy: ;inc if below 415 | inc yPos[esi] 416 | jmp continue 417 | decy: ;dec if above 418 | dec yPos[esi] 419 | jmp continue 420 | 421 | checky: ;old tail and the unit before is on the xAxis 422 | cmp yPos[esi-2], ah ;check if the new tail should be right or left of the old tail 423 | jl incx 424 | jg decx 425 | incx: ;inc if right 426 | inc xPos[esi] 427 | jmp continue 428 | decx: ;dec if left 429 | dec xPos[esi] 430 | 431 | continue: ;add snake tail and update new coin 432 | call DrawPlayer 433 | call CreateRandomCoin 434 | call DrawCoin 435 | 436 | mov dl,17 ; write updated score 437 | mov dh,1 438 | call Gotoxy 439 | mov al,score 440 | call WriteInt 441 | ret 442 | EatingCoin ENDP 443 | 444 | 445 | YouDied PROC 446 | mov eax, 1000 447 | call delay 448 | Call ClrScr 449 | 450 | mov dl, 57 451 | mov dh, 12 452 | call Gotoxy 453 | mov edx, OFFSET strYouDied ;"you died" 454 | call WriteString 455 | 456 | mov dl, 56 457 | mov dh, 14 458 | call Gotoxy 459 | movzx eax, score 460 | call WriteInt 461 | mov edx, OFFSET strPoints ;display score 462 | call WriteString 463 | 464 | mov dl, 50 465 | mov dh, 18 466 | call Gotoxy 467 | mov edx, OFFSET strTryAgain 468 | call WriteString ;"try again?" 469 | 470 | retry: 471 | mov dh, 19 472 | mov dl, 56 473 | call Gotoxy 474 | call ReadInt ;get user input 475 | cmp al, 1 476 | je playagn ;playagn 477 | cmp al, 0 478 | je exitgame ;exitgame 479 | 480 | mov dh, 17 481 | call Gotoxy 482 | mov edx, OFFSET invalidInput ;"Invalid input" 483 | call WriteString 484 | mov dl, 56 485 | mov dh, 19 486 | call Gotoxy 487 | mov edx, OFFSET blank ;erase previous input 488 | call WriteString 489 | jmp retry ;let user input again 490 | YouDied ENDP 491 | 492 | ReinitializeGame PROC ;procedure to reinitialize everything 493 | mov xPos[0], 45 494 | mov xPos[1], 44 495 | mov xPos[2], 43 496 | mov xPos[3], 42 497 | mov xPos[4], 41 498 | mov yPos[0], 15 499 | mov yPos[1], 15 500 | mov yPos[2], 15 501 | mov yPos[3], 15 502 | mov yPos[4], 15 ;reinitialize snake position 503 | mov score,0 ;reinitialize score 504 | mov lastInputChar, 0 505 | mov inputChar, "+" ;reinitialize inputChar and lastInputChar 506 | dec yPosWall[3] ;reset wall position 507 | Call ClrScr 508 | jmp main ;start over the game 509 | ReinitializeGame ENDP 510 | END main --------------------------------------------------------------------------------