基于flask實(shí)現(xiàn)五子棋小游戲
本文實(shí)例為大家分享了基于flask實(shí)現(xiàn)五子棋小游戲的具體代碼,供大家參考,具體內(nèi)容如下
前言
首先說(shuō)明一下,本人方向是java后端,只因老師布置了一個(gè)作業(yè),要用flask來(lái)做一個(gè)五子棋,沒(méi)辦法被逼上梁山,程序不太美觀,但是應(yīng)付作業(yè)還是夠了的。
廢話不多說(shuō),下面開(kāi)錘!
首先整個(gè)程序是一個(gè)web應(yīng)用,前端html+css+javaScript(有用到j(luò)query)(基本都是現(xiàn)學(xué)的,所以程序很多注釋也很丑),后端用的flask框架。
準(zhǔn)備工作
**1.**python環(huán)境、安裝flask
**2.**導(dǎo)入需要用到的包
pip install flask_cors pip install flask_sqlalchemy
**3.**創(chuàng)建一個(gè)flask項(xiàng)目,并將一下代碼復(fù)制運(yùn)行
文件結(jié)構(gòu)
不做代碼的生產(chǎn)者,只做代碼的搬運(yùn)工
前端
游戲頁(yè)面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>五子棋</title> <style> * { margin: 0; padding: 0; } body { margin-top: 20px; margin-left: 20px; } canvas { background-image: url("img/backgroud.jpg"); border: 1px solid #000; } .mybutton { width: 200px; line-height: 40px; text-align: center; background-color: cornflowerblue; margin: 0 auto; margin-top: 20px; font-size: 20px; color: #fff; } </style> </head> <body> <canvas width="600" height="600" onclick="play(event)"></canvas> <div> <input type="button" value="重新開(kāi)始" onclick="replay()" class="mybutton"> </div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> /*準(zhǔn)備工作: 1獲取畫布,獲取畫筆對(duì)象 */ var mcanvas = document.querySelector("canvas"); var ctx = mcanvas.getContext("2d"); /*準(zhǔn)備工作:2創(chuàng)建一個(gè)二維數(shù)組 用來(lái)定義繪制棋盤線*/ var count = 15;//用來(lái)定義棋盤的行數(shù)和列數(shù) var map = new Array(count); for (var i = 0; i < map.length; i++) { map[i] = new Array(count); for (var j = 0; j < map[i].length; j++) { map[i][j] = 0; } } /*準(zhǔn)備工作:3初始化棋子*/ var black = new Image(); var white = new Image(); black.src = "img/black.png"; white.src = "img/white.png"; //開(kāi)始繪制 1繪制棋盤線 ctx.strokeStyle = "#fff"; var rectWH = 40; //設(shè)置繪制矩形的大小 for (var i = 0; i < map.length; i++) { for (var j = 0; j < map[i].length; j++) { ctx.strokeRect(j * rectWH, i * rectWH, rectWH, rectWH); } } // 用來(lái)進(jìn)行黑白子的切換 var isBlack = true; //開(kāi)始繪制 2下子 function play(e) { //獲取點(diǎn)擊canvas的位置值默認(rèn),canvas的左上角為(0,0) 點(diǎn) var leftOffset = 20;//body 的margin var x = e.clientX - leftOffset; var y = e.clientY - leftOffset; // console.log(x+" "+y); // 設(shè)置點(diǎn)擊點(diǎn)后棋子下在哪里,獲取點(diǎn)擊的位置進(jìn)行判斷如果超過(guò)格子的一半則繪制到下一個(gè)點(diǎn)如果小于 則繪制在上一個(gè)點(diǎn)上 var xv = (x - rectWH / 2) / rectWH; var yv = (y - rectWH / 2) / rectWH; var col = parseInt(xv) + 1; var row = parseInt(yv) + 1; console.log(xv + " " + yv + " , " + col + " " + row); //嚴(yán)格點(diǎn)需要驗(yàn)證 ,驗(yàn)證所輸入的點(diǎn)是否在數(shù)組中已經(jīng)存在 ,如果存在 則返回 if (map[row][col] != 0) { alert("此處已經(jīng)落子"); return; } // 切換繪制黑白子 if (isBlack) { ctx.drawImage(black, col * 40 - 20, row * 40 - 20); isBlack = false; map[row][col] = 1; $.ajax({ url: "http://127.0.0.1:5000/yes",//請(qǐng)求的url地址 type: 'post',//設(shè)置請(qǐng)求的http方式,method也可以 dataType: 'json',//將服務(wù)器端返回的數(shù)據(jù)直接認(rèn)定為是這個(gè)格式,然后會(huì)做一些自動(dòng)的處理(如果是json字符串,會(huì)自動(dòng)轉(zhuǎn)化為js對(duì)象),服務(wù)器返回的默認(rèn)格式是text/html格式 data: {//向服務(wù)器端發(fā)送的數(shù)據(jù) t: 1, row: row, col: col, }, success: function (data) {//請(qǐng)求成功之后執(zhí)行的回調(diào)函數(shù) if(data.code===201){ alert('黑棋獲勝') }else if(data.code===202){ alert('白棋獲勝') } }, error: function(error){ console.log(error) } }); // Yes(1,row,col) } else { ctx.drawImage(white, col * 40 - 20, row * 40 - 20); isBlack = true; map[row][col] = 2; $.ajax({ url: "http://127.0.0.1:5000/yes",//請(qǐng)求的url地址 type: 'post',//設(shè)置請(qǐng)求的http方式,method也可以 dataType: 'json',//將服務(wù)器端返回的數(shù)據(jù)直接認(rèn)定為是這個(gè)格式,然后會(huì)做一些自動(dòng)的處理(如果是json字符串,會(huì)自動(dòng)轉(zhuǎn)化為js對(duì)象),服務(wù)器返回的默認(rèn)格式是text/html格式 data: {//向服務(wù)器端發(fā)送的數(shù)據(jù) t: 2, row: row, col: col, }, success: function (data) {//請(qǐng)求成功之后執(zhí)行的回調(diào)函數(shù) if(data.code===201){ alert('黑棋獲勝') }else if(data.code===202){ alert('白棋獲勝') } }, error: function(error){ console.log(error) } }); // Yes(2,row,col) } } function replay(){ $.ajax({ url: "http://127.0.0.1:5000/replay",//請(qǐng)求的url地址 type: 'post',//設(shè)置請(qǐng)求的http方式,method也可以 dataType: 'json',//將服務(wù)器端返回的數(shù)據(jù)直接認(rèn)定為是這個(gè)格式,然后會(huì)做一些自動(dòng)的處理(如果是json字符串,會(huì)自動(dòng)轉(zhuǎn)化為js對(duì)象),服務(wù)器返回的默認(rèn)格式是text/html格式 data: {//向服務(wù)器端發(fā)送的數(shù)據(jù) isReplay: true }, success: function (data) {//請(qǐng)求成功之后執(zhí)行的回調(diào)函數(shù) window.location.href = "game.html"; }, error: function(error){ console.log(error) } }); } /*功能擴(kuò)充: 1當(dāng)勝利后 彈框:a是否在來(lái)一局 b 精彩回復(fù) a 如果點(diǎn)擊在來(lái)一句 清空數(shù)據(jù)重新開(kāi)始 b 精彩回放將棋盤黑白子按照下棋的順序進(jìn)行棋子編號(hào)2悔棋功能 3對(duì)算法的擴(kuò)充 a如果是雙三 則直接彈出勝利 b若是桶四 則直接彈出勝利 */ </script> </body> </html>
登錄頁(yè)面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport"> <title></title> <style> * { margin: 0px; padding: 0px; } .title { font-size: 20px; background-color: cornflowerblue; color: #fff; /* * 里面的文字居中 */ line-height: 50px; text-align: center; /* *絕對(duì)定位 */ position: fixed; top: 0px; left: 0px; width: 100%; } .content { margin-top: 110px; } .mybutton { width: 200px; line-height: 40px; text-align: center; background-color: cornflowerblue; margin: 0 auto; margin-top: 20px; font-size: 20px; color: #fff; } .shurukuang { display: block; margin: 0 auto; width: 200px; height: 25px; margin-top: 1px; border: none; border-bottom: 1px solid; margin-top: 5px; text-indent: 4px; outline: none; } </style> </head> <body> <div class="title"> gobang賬戶登錄 </div> <div class="content"> <input id="username" class="shurukuang" type="text" placeholder="手機(jī)號(hào)" value="yokna"> <input id="password" class="shurukuang" type="password" placeholder="密碼" value="123456"> </div> <div class="mybutton" onclick="myClick()">登錄</div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> // 請(qǐng)求路徑 var httpurl = "http://127.0.0.1:5000/login"; // 數(shù)據(jù)請(qǐng)求 function myClick() { var usernamestr = document.getElementById("username").value; var passwordstr = document.getElementById("password").value; $.ajax({ url: httpurl,//請(qǐng)求的url地址 type: 'post',//設(shè)置請(qǐng)求的http方式,method也可以 dataType: 'json',//將服務(wù)器端返回的數(shù)據(jù)直接認(rèn)定為是這個(gè)格式,然后會(huì)做一些自動(dòng)的處理(如果是json字符串,會(huì)自動(dòng)轉(zhuǎn)化為js對(duì)象),服務(wù)器返回的默認(rèn)格式是text/html格式 data: {//向服務(wù)器端發(fā)送的數(shù)據(jù) username: usernamestr, password: passwordstr, }, success: function (data) {//請(qǐng)求成功之后執(zhí)行的回調(diào)函數(shù) console.log(data.code); if(data.code!==200){ alert("用戶名或密碼錯(cuò)誤") }else{ window.location.href = "game.html"; } }, error: function(error){ console.log(error) } }); } </script> </body> </html>
歡迎界面
說(shuō)明:此界面可有可無(wú),對(duì)整個(gè)游戲沒(méi)有影響
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script type="text/javascript"> window.onload = function f(){ var myDate = new Date(); document.getElementById('currentTime').innerText = myDate.getTime(); } function loadPage(){ var targetURL = document.querySelector('#url').value; console.log(targetURL); document.querySelector('#iframePosition').src = targetURL; } </script> <div> 歡迎來(lái)玩五子棋: <input type="text" id="url" value="http://127.0.0.1:5500/templates/game.html" hidden> <input type="button" value="開(kāi)始游戲" onclick="loadPage()"> </div> <div> <h3>加載頁(yè)面的位置</h3> <iframe style="width: 100%;height: 600px" id="iframePosition"> </iframe> </div> </body> </html>
至此,前端的頁(yè)面就展示完了
下面是后端的內(nèi)容
后端
配置文件
SQLALCHEMY_DATABASE_URI = "mysql://root:password@localhost:3306/gobang" # "數(shù)據(jù)庫(kù)://用戶名:密碼@host:port/數(shù)據(jù)庫(kù)名稱" SQLALCHEMY_TRACK_MODIFICATIONS = False # 這一行不加會(huì)有警告
啟動(dòng)類
# -*- coding:utf-8 -*- #1.導(dǎo)入flask擴(kuò)展 # 2.創(chuàng)建flask應(yīng)用程序?qū)嵗? # 3.定義路由及視圖函數(shù) # 4.啟動(dòng)程序 from flask import Flask, render_template, request from flask_cors import * import pymysql pymysql.install_as_MySQLdb() from flask_sqlalchemy import SQLAlchemy import config #需要傳入__name__ 為了確定資源所在路徑 app = Flask(__name__) CORS(app, supports_credentials=True) app.config.from_object(config) db = SQLAlchemy(app) global map map = [[0 for i in range(15)] for j in range(15)] # #flask中定義路由是通過(guò)裝飾器來(lái)實(shí)現(xiàn)的,訪問(wèn)路由會(huì)自動(dòng)調(diào)用路由下跟的方法,并將執(zhí)行結(jié)果返回 @app.route('/login',methods=["GET","POST"]) def login(): if request.method == "POST": # 以POST方式傳參數(shù),通過(guò)form取值 # 如果Key之不存在,報(bào)錯(cuò)KeyError,返回400的頁(yè)面 username = request.form['username'] password = request.form['password'] user = queryUser(username,password) if len(user) > 0: return {"code": 200, "msg": "成功"} else: return {"code": 400, "msg": "驗(yàn)證失敗"} println('驗(yàn)證失敗') print(username+password) else: # 以GET方式傳參數(shù),通過(guò)args取值 username = request.args['username'] print(username) return {"code": 200,"msg":"成功"} class User(db.Model): __tablename__ = 'user' username = db.Column(db.String(255)) password = db.Column(db.String(255)) id = db.Column(db.Integer,primary_key=True) def index(): user = User(username='你好你好',password='456456') #調(diào)用添加方法 db.session.add(user) #提交入庫(kù),上面已經(jīng)導(dǎo)入了提交配置,所以不需要在提交了 db.session.commit() return '這是首頁(yè)' def queryUser(username,password): user = User.query.filter_by(username=username,password=password).all() db.session.commit() return user @app.route('/replay',methods=["POST"]) def replay(): global map map = [[0 for i in range(15)] for j in range(15)] return {"code": 200,"msg":"成功"} @app.route('/yes',methods=["POST"]) def yes(): print('this is yes ') t = int(request.form['t']) print(t) tmprow = request.form['row'] print(tmprow) tmpcol = request.form['col'] print(tmpcol) row = int(tmprow) col = int(tmpcol) total = 1 map[int(row)][int(col)] = t chessboard = map print(chessboard) print('this is yes ') print(t) print(tmprow) print(tmpcol) #不寫注釋真容易看混,本少俠就勉強(qiáng)寫一點(diǎn)吧 #這里是要判斷水平方向上是否滿足獲勝條件 while col - 1 > 0 and chessboard[row][col - 1] == t: total = total + 1 col = col - 1 row = int(tmprow) col = int(tmpcol) while col + 1 < 15 and chessboard[row][col + 1] == t: total = total + 1 col = col + 1 if total >= 5: if t == 1: return {"code": 201, "msg": "黑棋獲勝"} else: return {"code": 202, "msg": "白棋獲勝"} #判斷垂直方向上是否滿足獲勝條件 row = int(tmprow) col = int(tmpcol) while row - 1 > 0 and chessboard[row - 1][col] == t: total = total + 1 row = row - 1 row = int(tmprow) col = int(tmpcol) while row + 1 < 15 and chessboard[row + 1][col] == t: total = total + 1 row = row + 1 if total >= 5: if t == 1: return {"code": 201, "msg": "黑棋獲勝"} else: return {"code": 202, "msg": "白棋獲勝"} #判斷pie上是否滿足獲勝條件 row = int(tmprow) col = int(tmpcol) while row - 1 > 0 and col + 1 < 15 and chessboard[row - 1][col + 1] == t: total = total + 1 row = row - 1 col = col + 1 row = int(tmprow) col = int(tmpcol) while row + 1 < 15 and col - 1 > 0 and chessboard[row + 1][col - 1] == t: total = total + 1 row = row + 1 col = col - 1 if total >= 5: if t == 1: return {"code": 201, "msg": "黑棋獲勝"} else: return {"code": 202, "msg": "白棋獲勝"} #判斷na上是否滿足獲勝條件 row = int(tmprow) col = int(tmpcol) while row - 1 > 0 and col - 1 > 0 and chessboard[row - 1][col - 1] == t: total = total + 1 row = row - 1 col = col - 1 row = int(tmprow) col = int(tmpcol) while row + 1 < 15 and col + 1 < 15 and chessboard[row + 1][col + 1] == t: total = total + 1 row = row + 1 col = col + 1 if total >= 5: if t == 1: return {"code": 201, "msg": "黑棋獲勝"} else: return {"code": 202, "msg": "白棋獲勝"} return {"code": 203, "msg": "繼續(xù)"} #會(huì)運(yùn)行起一個(gè)小型服務(wù)器,就會(huì)將我們的flask程序運(yùn)行在一個(gè)簡(jiǎn)單的服務(wù)器上,服務(wù)器由flask提供,用于測(cè)試 if __name__ == '__main__': app.run()
數(shù)據(jù)庫(kù)表
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `password` varchar(255) NOT NULL, `id` int(16) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('yokna', '123456', '1'); INSERT INTO `user` VALUES ('你好你好', '456456', '2'); INSERT INTO `user` VALUES ('你好你好', '456456', '3'); INSERT INTO `user` VALUES ('orange', '123456', '4');
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python版本五子棋的實(shí)現(xiàn)代碼
- python實(shí)現(xiàn)五子棋小游戲
- python pygame實(shí)現(xiàn)五子棋小游戲
- python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
- python實(shí)現(xiàn)五子棋小程序
- 使用python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
- python實(shí)現(xiàn)五子棋游戲
- python實(shí)現(xiàn)五子棋游戲(pygame版)
- python使用minimax算法實(shí)現(xiàn)五子棋
- python五子棋游戲的設(shè)計(jì)與實(shí)現(xiàn)
相關(guān)文章
使用Python Flask實(shí)現(xiàn)簡(jiǎn)易文件上傳功能
在平時(shí)工作中,文件上傳是一項(xiàng)常見(jiàn)的需求,例如將應(yīng)用異常時(shí)通過(guò)腳本生成的dump文件收集起來(lái)進(jìn)行分析,但實(shí)現(xiàn)起來(lái)卻可能相當(dāng)復(fù)雜,在本文中,我們將探討如何使用Flask實(shí)現(xiàn)文件上傳功能,編寫Dockerfile將應(yīng)用程序通過(guò)docker部署,需要的朋友可以參考下2024-05-05Python 運(yùn)行 shell 獲取輸出結(jié)果的實(shí)例
今天小編就為大家分享一篇Python 運(yùn)行 shell 獲取輸出結(jié)果的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01python求numpy中array按列非零元素的平均值案例
這篇文章主要介紹了python求numpy中array按列非零元素的平均值案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06Python使用Appium在移動(dòng)端抓取微博數(shù)據(jù)的實(shí)現(xiàn)
Appium是移動(dòng)端的自動(dòng)化測(cè)試工具,讀者可以類比為PC端的selenium。通過(guò)它,我們可以驅(qū)動(dòng)App完成自動(dòng)化的一系列操作,同樣也可以爬取需要的內(nèi)容,本文就來(lái)介紹一下如何在移動(dòng)端抓取微博數(shù)據(jù),感興趣的可以了解一下2021-08-0860行Python PyGame代碼實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲
這篇文章主要為大家詳細(xì)介紹如何通過(guò)了60行Python PyGame代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)單的迷宮游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2023-12-12python Web應(yīng)用程序測(cè)試selenium庫(kù)使用用法詳解
selenium主要是用來(lái)做自動(dòng)化測(cè)試,支持多種瀏覽器,爬蟲中主要用來(lái)解決JavaScript渲染問(wèn)題本文詳細(xì)介紹了在python中selenium模塊的使用方法2021-10-10python通過(guò)函數(shù)名調(diào)用函數(shù)的幾種場(chǎng)景
這篇文章主要介紹了python通過(guò)函數(shù)名調(diào)用函數(shù)的幾種場(chǎng)景,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09