简易三子棋游戏实现
哈嘍小伙伴們大家好,我們一起學習三子棋游戲的創(chuàng)建吧。在開始之前我們先來復習一下,函數(shù)聲明放在頭文件中函數(shù)定義放在源文件中。那么什么是函數(shù)聲明和函數(shù)定義呢?所謂函數(shù)聲明就是說明函數(shù)的返回參數(shù),函數(shù)類型,函數(shù)名。但具體存不存在,這可不歸他管。函數(shù)定義就更加簡單了,說明函數(shù)的具體實現(xiàn)功能。接來下我們正式開始學習吧
在開始三子棋之前我們需要三個文件test.c文件用于測試,game.h用于放置函數(shù)聲明,game.c放置函數(shù)定義。OK接著開始吧
一般來說,一打開游戲就會彈出一個游戲菜單讓用戶選擇是開始玩游戲還是退出游戲。并且再玩過一把之后選擇再來一把還是結(jié)束游戲。對于這種我們選擇用do while()函數(shù),因為do while的特點是先執(zhí)行在判斷。這一點就符合我們的游戲設計的需要。然后應該在do while()函數(shù)中放置菜單函數(shù)。此時先來設計菜單內(nèi)容,大致內(nèi)容就是選擇1開始游戲,選擇0退出游戲。到這里一個簡單的菜單就設計好了,如圖
在游戲中出現(xiàn)菜單之后,提示用戶就進行選擇是退出游戲還是開始游戲。對于用戶的輸入我們也要進行判斷,此時在do while()函數(shù)中可以用一個switch語句來解決,當然這里也可以用if else語句來解決不過略微的麻煩一點。
也有小伙伴可能也會有疑問說,為啥要有default語句項呢為啥do while()中while后的括號中放的是input呢?這里來說明一下,當用戶輸入的既不是1也不是0,那么此時我們該提醒一下用戶輸入錯誤讓用戶重新選擇。至于while()判斷部分為啥要放input則更簡單啦,判斷部分非0為真進入循環(huán),0為假跳出循環(huán),當輸入既不是1也不是0是依舊會進入循環(huán)也就是進入游戲。
解決完這些,我們要在case 1中分裝一個game()函數(shù),此時才正式進入三子棋代碼實現(xiàn)部分。如圖,
我們會發(fā)現(xiàn)三子棋棋盤和二維數(shù)組的打印是一致的,這就說明我們可以用一個char類型的二維數(shù)組來表示棋盤。倘若我們要一個3*3大小的棋盤,則可以寫成char board[3][3];但是這種寫法的話棋盤的大小就固定了,當想換成5*5或者更大的棋盤是就會顯得不方便。該如何解決呢?沒錯就在頭文件中用define來定義常量,這樣想修改時只需要在頭文件修改即可。而且只需要引用一下game.h就好了
再來初始化棋盤,把棋盤的全部內(nèi)容都初始化為空格。用到一個InitBoard函數(shù),初始化的方式也簡單遍歷一遍數(shù)組把每個賦值為空格即可。這里我們把函數(shù)聲明依舊放在game.h中,InitBoard函數(shù)定義放在game.c文件中。注意:在game.c中也要引用game.h
接下來就是打印棋盤,先準備一個DisplayBoard函數(shù),同樣它的實現(xiàn)放在game.c中聲明放在game.h中
以3*3的棋盤為例,我們可以把打印字符和|看成一組,把---和|看成一組。同時呢在打印第三組字符之后不在打印|,第三組---也是同樣不打印|。再往下看會發(fā)現(xiàn)第三組字符和|打印之后就不在打印了。這些是我們需要注意的問題避免打印圖案錯誤。那我們?nèi)绾蝸泶蛴∧?#xff0c;來,上代碼(等!等!在打印字符和|之后要進行換行)
此時呢棋盤初始化也并且打印好了,接下來就該來到下棋部分了。在此之前玩家下棋用‘*’表示,電腦下棋用‘#’表示。下棋嘛先讓玩家進行下棋如何打印棋盤,再判斷輸贏。然后再有電腦下棋,打印棋盤,判斷輸贏。這個是個循環(huán)過程,畢竟不能一次就下成功了叭。所以要用一個while()循環(huán),判斷部分就放一個非0的,當判斷玩家贏或者電腦贏或者平局的時候就跳出循環(huán)。先開始玩家下棋,這不得來個PlayerMove函數(shù)來實現(xiàn),函數(shù)參數(shù)放進去數(shù)組名,行,列。具體實現(xiàn)依舊放在game.c中來。不過這里還需要注意一個問題,在二維數(shù)組中,行和列都是從0開始。但是玩家可不是程序員,他可不會從0開始,一般會從1開始。而且輸入的坐標也不一定就是在棋盤之中。所以在PlayerMove函數(shù)中先進行判斷,要是符合棋盤的行列就繼續(xù)判斷,不符合則提醒一下玩家坐標非法。當坐標合法之后,倘若玩家輸入的坐標是空格沒被占用的話則繼續(xù)輸入,反之則提醒玩家輸入的坐標已經(jīng)被占用,再玩家輸入之后再來打印棋盤??谡f無憑,那不得上代碼
玩家下棋結(jié)束之后再來電腦下棋,判斷輸贏先不急?(・ω・)ノ
電腦下棋也要一個函數(shù)來實現(xiàn),就淺淺的把這個函數(shù)稱之為ComputerMove.依舊是把函數(shù)名,行列傳過去,具體實現(xiàn)在game.c中聲明在game.h中。電腦下棋就不要太復雜,隨機生成坐標然后再判斷一下生成的坐標有沒有被占用,被占用的話就再生成一個反之則下棋并跳出循環(huán),電腦下棋完成之后依舊要打印棋盤。那么問題又來了如何生成隨機坐標呢?小伙伴們還記得rand函數(shù)嗎,rand函數(shù)可以生成隨機坐標(記得引用對應頭文件諾)。但是電腦下棋的隨機坐標必須是要符合棋盤行列的,這可咋辦呢?是的沒錯,電腦生成的行坐標用rand()%ROW,列坐標用rand()%COL.可能又有小伙伴有疑問了為啥要這樣寫!以3*3棋盤為例,行和列的范圍都是0~2,這種用rand()%3就能得到范圍。還有一個需要注意的是:在使用rand函數(shù)之前必須使用srand(),詳情請看
上代碼
終于來到了判斷是輸贏的部分了,判斷輸贏的話會有四種結(jié)果:玩家贏,電腦贏,平局,繼續(xù)。平局就是棋盤已經(jīng)滿了。當玩家贏時返回‘*’,電腦贏時返回‘#’,平局返回‘q’,繼續(xù)游戲返回‘c’。不管是玩家贏還是電腦贏,都說明棋盤上的三行或三列,一撇亦或是一捺連成三個。但一定要注意這幾個都不能是空格。否則在玩家下棋之后就會直接結(jié)束游戲(小編昨天寫的代碼會寫成這樣的,嗚嗚嗚)。既不是電腦贏也不是玩家贏的話,要進行判斷棋盤是否滿了,滿了的話平局,反之則游戲繼續(xù)。分析到此,我們在判斷輸贏時用一個char型的is_win函數(shù)來進行判斷并且返回值,倘若返回的是‘c’游戲繼續(xù),不是‘c’跳出循環(huán)。跳出循環(huán)之后再對返回值進行判斷,為避免麻煩可以用一個char ret 來接收is_win的返回值。倘若ret是‘*’,則打印玩家贏。若是‘#’,則打印電腦贏。若是‘q’,則打印平局。分析結(jié)束,上代碼
OK,代碼到這里就設計完成了來看看實現(xiàn)效果吧
最后就是整個代碼啦
請問堅持到這的勇士還有多少,敬勇士。以上就是今天所有的內(nèi)容。勇士們記得一鍵三連吶么么噠
總結(jié)
- 上一篇: 数据流分析基础和局域网基础
- 下一篇: Windows电脑快速打开heic文件方