https://www.linkedin.com/in/danial-rahimy
ساخت بازی سنگ، کاغذ، قیچی با پایتون
در این مطلب قصد دارم شما رو با پایتون بیشتر آشنا کنم و با هم بازی خاطره انگیز سنگ، کاغذ، قیچی رو بنویسم. امیدوارم در این چند دقیقه ای که با هم هستیم لحظات خوشی داشته باشیم.
پیش نیاز
- آشنایی با پایتون به صورت مقدماتی
توضیحی در رابطه با بازی
بازی به صورت چند زبانه طراحی شده است.
همچنین در هر تعامل، کاربر امکان خروج از بازی را دارد.
مراجل بازی:
- کاربر زبان مورد نظر خود را انتخاب می کند.
- کاربر امکان انتخاب تعداد دست بازی را دارد. می تواند نامحدود نیز باشد.
- کاربر از بین سنگ، کاغذ، قیچی یکی را انتخاب می کند.
- اپلیکیشن به صورت رندوم برای خود از موارد یکی را انتخاب می کند و سپس نتیجه را اعلام می کند
پرسه بالا تا زمان به اتمام رسیدن تعداد دست های بازی یا خارج شدن کاربر ادامه پیدا می کند.
- پس از اتمام بازی خلاصه ای از وضعیت بازی که شامل تعداد دست بازی شده، تعداد بردهای کاربر، تعداد برد های اپلیکیشن، تعداد مساوی ها و همچنین برنده نهایی بازی نمایش داده می شود.
جهت مشاهده ویدیو خروجی بازی در آپارات کلیک کنید
قدم به قدم پیش می رویم
به دلیل اینکه بهتر با طرز تفکر نحوه کد نویسی برای انجام یک پروژه آشنا شوید کد به صورت خط به خط نوشته نمی شود و ممکن است نیاز باشد به خط های بالاتر کدی اضافه شود یا تغییر کند. چون در واقعیت امر به این شکل است که با توجه به طرز تفکر برنامه نویس و پیشبرد کار کد ها اصلاح می شود و به این صورت نیست که از ابتدا تا انتها یک دست کد ها نوشته شود. البته که با افزایش مهارت و انجام تمرین بیشتر به این سمت پیش خواهید رفت که بدانید در چند خط آینده چه خواهید نوشت پس پیش نیاز آن را نیز می نویسید که نیاز به بازگشت و اصلاح کد های قبلی نباشد.
شروع کد نویسی
سورس کد به صورت یکجا در انتهای پست قرار دارد.
در ابتدا متغییری از نوع دیکشنری با نام messagesInAllLanguages تعریف می کنیم که حاوی پیام ها و سوالاتی است که برای تعامل با کاربر به آن ها نیاز داریم. از آن جایی که این بازی چند زبانه است به صورت ساختاری که زبان ها در کلید متغییر قرار می گیرند و جملات در مقدار آن تعریف می شود.
با توجه به ساختار زیر که جملات برای زبان انگلیسی و اسپانیایی نوشته شده است به راحت می توانید گسترش دهید و زبان های دیگر را نیز به آن اضافه کنید. فقط کافی است مقادیر کلید هر عنوان را ترجمه کنید.
messagesInAllLanguages = {
"en": {
"welcome": "Welcome to the game",
"choose language": "Please choose your language en, es, (q to exit): ",
"choose action": "Please choose between stone(st), paper(pa), scissors(sc) (q to exit): ",
"bye": "We're glad you used our game. hope to see you again",
"user score": "Your score: {0}",
"app score": "App's score: {0}",
"equal round": "equal round: {0}",
"equal rounds": "equal rounds: {0}",
"same action": "whoops! you and app select the same",
"app win round": "App wins round",
"user win round": "You win round",
"app win game": "App wins game",
"user win game": "You win game",
"same result": "Whoops! you and app has the same score",
"app chosen": "App chosen: {0}",
"game round": "How many rounds do you want to play (-1 for unlimited)? (q to exit) ",
"play round": "You play 1 round",
"play rounds": "You play {0} rounds",
},
"es": {
"welcome": "Bienvenida al juego",
"choose language": "Elija su idioma en, es, (q para salir): ",
"choose action": "Elija entre piedra(pi), papel(pa), tijeras(ti) (q para salir): ",
"bye": "Nos alegra que hayas usado nuestro juego. espero verte de nuevo",
"user score": "Tu puntuación: {0}",
"app score": "Puntuación de la aplicación: {0}",
"equal round": "ronda igual: {0}",
"equal rounds": "rondas iguales: {0}",
"same action": "¡Ups! dusted y la aplicación seleccionan lo mismo",
"app win round": "La aplicación gana ronda",
"user win round": "Tu ganas ronda",
"app win game": "La aplicación gana el juego",
"user win game": "Tu ganas el juego",
"same result": "¡Ups! tú y la aplicación tienen la misma puntuación",
"app chosen": "Aplicación elegida: {0}",
"game round": "¿Cuántas rondas quieres jugar (-1 para ilimitado)? (q para salir) ",
"play round": "Tu juegas 1 ronda",
"play rounds": "Juegas {0} rondas",
}
}
در ابتدا متغییری با نام languages از نوع لیست تعریف می کنیم که دارای کلید های متغییر messagesInAllLanguages است که مقدار آن نام زبان های بازی می شود.
languages = list(messagesInAllLanguages.keys())
متغیری با نام language تعریف می کنیم و به صورت پیشفرض زبان را روی en قرار می دهیم.
language = "en"
متغییری با نام quitApp تعریف می کنیم که مقدار اولیه False دارد و با توجه به اسم آن مشخص کننده نگهدارنده وضعیت خروج از بازی است که بعدا با ورودی که از کاربر گرفته می شود در صورت نیاز True می شود.
quitApp = False
در یک while اقدام به پرسیدن زبان بازی از کاربر می کنیم به این دلیل که اگر به درستی پاسخ نداد آن قدر این پرسه تکرار شود تا پاسخ مورد انتظار ما دریافت شود.
پرسش انتخاب زبان را از کاربر می پرسیم و در متغییر language نگه داری می کنیم. آن را به حروف کوچک تبدیل می کنیم. با انجام این کار، امکان این که کاربر با حرف بزرگ و یا ترکیبی وارد کند را داده ایم. می تواند در تعامل با کاربر حس خوبی به وجود آورد.
while True:
language = input(messagesInAllLanguages["en"]["choose language"])
language = language.lower()
بررسی می کنیم که اگر زبان وارد شده کاربر جز زبان های بازی بود لوپ را بشکند و بازی به جریان خود ادامه دهد.
if language in languages:
break
در غیر اینصورت بررسی می کنیم که اگر کاربر q را به جهت خروج وارد کرده است لوپ بشکند و ادامه روند پیش برد. نکته قابل توجه این که چون کاربر در پاسخ پرسش q وارد کرده است و مقدار را در language ریخته ایم دوباره به صورت پیشفرض en را قرار می دهیم و مقدار متغییر quitApp را نیز برابر True قرار می دهیم.
if language == "q":
language = "en"
quitApp = True
break
اگر هیچ کدام از حالت های بالا رخ ندهد یعنی کاربر زبان درستی را وارد نکرده است که باعث می شود while به کار خود ادامه دهد و روند بالا از اول تکرار شود.
در قسمت قبل زبان بازی مشخص شده و با استفاده از آن پیام های زبان مورد نظر را در متغییر messages قرار می دهیم.
messages = messagesInAllLanguages[language]
سپس دو متغییر originalGameRound و gameRoundRemind که به ترتیب نگه دارنده تعداد دست انتخاب شده توسط کاربر و تعداد دست باقی مانده از بازی هستند که به صورت پیشفرض 0 مقدار دهی می شوند.
originalGameRound = gameRoundRemind = 0
پیام خوش آمد گویی به کاربر نمایش داده می شود.
print(messages["welcome"])
در while اقدام به پرسش از کاربر جهت دریافت تعداد دست هایی که میخواهد بازی کند می کنیم و مقدار را در متغییر gameRoundRemind ذخیره می کنیم.
while not quitApp:
gameRoundRemind = input(messages["game round"])
بررسی میکنیم که اگر مقدار q را جهت خروج از بازی وارد کرده است لوپ شکسته شود و مقدار متغییر quitApp را True قرار می دهیم.
if gameRoundRemind == "q":
quitApp = True
break
بررسی می کنیم که اگر مقدار دریافت شده از کاربر عددی نباشد و -1 نیز نباشد (-1 برای دست نامحدود است) لوپ کار خود از ابتدا شروع کند.
if not gameRoundRemind.isdecimal() and gameRoundRemind != "-1":
continue
اگر اتفاق بالا نیفتاد پس ورودی کاربر صحیح است و مقدار دریافتی از کاربر را به نوع عدد تبدیل می کنیم و سپس آن را در متغییر های gameRoundRemind و originalGameRound که از قبل تعریف کرده ایم قرار می دهیم.
gameRoundRemind = originalGameRound = int(gameRoundRemind)
با استفاده از کلمه کلیدی break لوپ را می شکنیم که روند بازی ادامه پیدا کند.
break
در ادامه مقادیر سنگ، کاغذ، قیچی را با توجه به زبان های بازی تعریف می کنیم و در کلید long در هر زبان قرار می دهیم اگر توجه کنید برای هر مقدار یک کلید wins against تعریف کرده ایم که نشان دهنده این است که در مقابل چه چیزی برنده است. به عنوان مثال: سنگ در مقابل قیچی برنده می شود پس مقدار آن کلید برابر با قیچی است.
کلید short در هر زبان نشان دهنده مخفف ها است که به عنوان مثل کاربر به جای وارد کردن stone از st استفاده می کند که در بازی با استفاده از مقادیر short آن را با مقدار کامل خود جایگزین می کنیم.
در ادامه که از این دیکشنری استفاده کنیم بهتر این توضیحات را درک خواهید کرد.
actionsDetails = {
"en": {
"short": {
"st": "stone",
"pa": "paper",
"sc": "scissors",
},
"long": {
"stone": {
"wins against": ["scissors"]
},
"paper": {
"wins against": ["stone"]
},
"scissors": {
"wins against": ["paper"]
}
}
},
"es": {
"short": {
"pi": "piedra",
"pa": "papel",
"ti": "tijeras",
},
"long": {
"piedra": {
"wins against": ["tijeras"]
},
"papel": {
"wins against": ["piedra"]
},
"tijeras": {
"wins against": ["papel"]
}
}
}
}
در دو متغییر actionsLong و actionsShort، همانطور که از نام آن ها مشخص است با توجه به زبان انتخاب شده مقادیر short و long را در آن نگه داری می کنیم.
actionsLong = list(actionsDetails[language]["long"].keys()) actionsShort = actionsDetails[language]["short"]
در ادامه در while با کاربر تعامل میکنیم و بازی شروع می شود.
متغییری با نام scores از نوع دیکشنری تعریف می کنیم که امتیاز کاربر و بازی را در خود نگه داری می کند.
scores = {"user": 0, "app": 0}
در تعامل با کاربر گزینه مورد نظر او از میان سنگ، کاغذ و قیچی را دریافت می کنیم. در متغییر action مقادیر انتخاب شده کاربر و بازی (به صورت رندم) را نگه داری می کنیم. مقدار دریافت شده از کاربر را به حروف کوچک تبدیل می کنیم.
while gameRoundRemind != 0:
action = {
"user": input(messages["choose action"]),
"app": random.choice(actionsLong)
}
action["user"] = action["user"].lower()
بررسی میکنیم که اگر کابر q را جهت خروج انتخاب کرده است لوپ بشکند و روند بازی ادامه پیدا کند.
if action["user"] == "q":
quitApp = True
break
گر کاربر مقدار مخفف را وارد کرده باشد به مقدار اصلی تبدیل کنیم.
longFromShort = actionsShort.get(action["user"])
if longFromShort:
action["user"] = longFromShort
اگر مقدار وارد شده کاربر صحیح نباشد لوپ از اول اجرا می شود و پروسه بالا تکرار می شود.
if action["user"] not in actionsLong:
continue
جهت جدا شدن پیغام ها از سوالات تعداد * چاپ می کنیم. مقدار انتخاب شده توسط سیستم به کاربر نمایش داده می شود.
print("*" * 40)
print(messages["app chosen"].format(action["app"]))
بررسی می شود که اگر مقدار انتخابی کاربر و سیستم یکی باشد اقدامی صورت نگیرد و صرفا پیغامی جهت این مورد به کاربر نمایش داده می شود.
اگر مقدار وارد شده کاربر جز لیست برندگان مورد انتخاب سیستم باشد، پس سیستم برنده است و به امتیاز او اضافه می کنیم و پیغام مناسب نمایش داده می شود.
در غیر اینصورت کاربر برنده است و به امتیاز او اضافه می کنیم و پیغام نمایش داده می شود.
if action["user"] == action["app"]:
print(messages["same action"])
elif action["user"] in actionsDetails[language]["long"][action["app"]]["wins against"]:
scores["app"] += 1
print(messages["app win round"])
else:
scores["user"] += 1
print(messages["user win round"])
در انتها از مقدار دست های بازی یکی کم می شود و پروسه بالا تا انتهای بازی ادامه پیدا می کند.
print("*" * 40)
gameRoundRemind -= 1
با بررسی شرط زیر متوجه می شویم که کاربر بازی انجام داده است یا خیر. و کد های بعد از آن در صورت True بودن شرط اجرا می شود.
if originalGameRound != gameRoundRemind:
محاسبه می کنیم که چند دست بازی انجام شده است.
gameRoundPlayed = originalGameRound - gameRoundRemind
تعداد دست های بازی شده را نمایش می دهیم. اگر یک بازی انجام شده باشد داخل if اجرا می شود و در غیر اینصورت else
if (originalGameRound - 1) == gameRoundRemind:
print(messages["play round"])
else:
print(messages["play rounds"].format(originalGameRound - gameRoundRemind))
تعداد برد های کاربر و سیستم را نمایش می دهیم.
print(messages["user score"].format(scores["user"]))
print(messages["app score"].format(scores["app"]))
تعداد مساوی ها را محاسبه می کنیم و بررسی می کنیم اگر بیشتر از 0 است نمایش داده شود.
اگر برابر 1 است داخل if در غیر اینصورت else اجرا می شود.
equal = gameRoundPlayed - (scores["user"] + scores["app"])
if equal == 1:
print(messages["equal round"].format(equal))
elif equal > 1:
print(messages["equal rounds"].format(equal))
با توجه به وضعیت بازی که کاربر یا سیستم برنده شده است و یا مساوی شده اند پیغام مناسب نمایش داده می شود.
if scores["user"] > scores["app"]:
print(messages["user win game"])
elif scores["user"] < scores["app"]:
print(messages["app win game"])
else:
print(messages["same result"])
در انتهای بازی هم پیغام خداحافظی نمایش می دهیم!
print(messages["bye"])
کد نهایی به صورت زیر خواهد بود
import random
messagesInAllLanguages = {
"en": {
"welcome": "Welcome to the game",
"choose language": "Please choose your language en, es, (q to exit): ",
"choose action": "Please choose between stone(st), paper(pa), scissors(sc) (q to exit): ",
"bye": "We're glad you used our game. hope to see you again",
"user score": "Your score: {0}",
"app score": "App's score: {0}",
"equal round": "equal round: {0}",
"equal rounds": "equal rounds: {0}",
"same action": "whoops! you and app select the same",
"app win round": "App wins round",
"user win round": "You win round",
"app win game": "App wins game",
"user win game": "You win game",
"same result": "Whoops! you and app has the same score",
"app chosen": "App chosen: {0}",
"game round": "How many rounds do you want to play (-1 for unlimited)? (q to exit) ",
"play round": "You play 1 round",
"play rounds": "You play {0} rounds",
},
"es": {
"welcome": "Bienvenida al juego",
"choose language": "Elija su idioma en, es, (q para salir): ",
"choose action": "Elija entre piedra(pi), papel(pa), tijeras(ti) (q para salir): ",
"bye": "Nos alegra que hayas usado nuestro juego. espero verte de nuevo",
"user score": "Tu puntuación: {0}",
"app score": "Puntuación de la aplicación: {0}",
"equal round": "ronda igual: {0}",
"equal rounds": "rondas iguales: {0}",
"same action": "¡Ups! dusted y la aplicación seleccionan lo mismo",
"app win round": "La aplicación gana ronda",
"user win round": "Tu ganas ronda",
"app win game": "La aplicación gana el juego",
"user win game": "Tu ganas el juego",
"same result": "¡Ups! tú y la aplicación tienen la misma puntuación",
"app chosen": "Aplicación elegida: {0}",
"game round": "¿Cuántas rondas quieres jugar (-1 para ilimitado)? (q para salir) ",
"play round": "Tu juegas 1 ronda",
"play rounds": "Juegas {0} rondas",
}
}
languages = list(messagesInAllLanguages.keys())
language = "en"
quitApp = False
while True:
language = input(messagesInAllLanguages["en"]["choose language"])
language = language.lower()
if language in languages:
break
if language == "q":
language = "en"
quitApp = True
break
messages = messagesInAllLanguages[language]
originalGameRound = gameRoundRemind = 0
print(messages["welcome"])
while not quitApp:
gameRoundRemind = input(messages["game round"])
if gameRoundRemind == "q":
quitApp = True
break
if not gameRoundRemind.isdecimal() and gameRoundRemind != "-1":
continue
gameRoundRemind = originalGameRound = int(gameRoundRemind)
break
actionsDetails = {
"en": {
"short": {
"st": "stone",
"pa": "paper",
"sc": "scissors",
},
"long": {
"stone": {
"wins against": ["scissors"]
},
"paper": {
"wins against": ["stone"]
},
"scissors": {
"wins against": ["paper"]
}
}
},
"es": {
"short": {
"pi": "piedra",
"pa": "papel",
"ti": "tijeras",
},
"long": {
"piedra": {
"wins against": ["tijeras"]
},
"papel": {
"wins against": ["piedra"]
},
"tijeras": {
"wins against": ["papel"]
}
}
}
}
actionsLong = list(actionsDetails[language]["long"].keys())
actionsShort = actionsDetails[language]["short"]
scores = {"user": 0, "app": 0}
while gameRoundRemind != 0:
action = {
"user": input(messages["choose action"]),
"app": random.choice(actionsLong)
}
action["user"] = action["user"].lower()
if action["user"] == "q":
quitApp = True
break
longFromShort = actionsShort.get(action["user"])
if longFromShort:
action["user"] = longFromShort
if action["user"] not in actionsLong:
continue
print("*" * 40)
print(messages["app chosen"].format(action["app"]))
if action["user"] == action["app"]:
print(messages["same action"])
elif action["user"] in actionsDetails[language]["long"][action["app"]]["wins against"]:
scores["app"] += 1
print(messages["app win round"])
else:
scores["user"] += 1
print(messages["user win round"])
print("*" * 40)
gameRoundRemind -= 1
if originalGameRound != gameRoundRemind:
gameRoundPlayed = originalGameRound - gameRoundRemind
if (originalGameRound - 1) == gameRoundRemind:
print(messages["play round"])
else:
print(messages["play rounds"].format(originalGameRound - gameRoundRemind))
print(messages["user score"].format(scores["user"]))
print(messages["app score"].format(scores["app"]))
equal = gameRoundPlayed - (scores["user"] + scores["app"])
if equal == 1:
print(messages["equal round"].format(equal))
elif equal > 1:
print(messages["equal rounds"].format(equal))
if scores["user"] > scores["app"]:
print(messages["user win game"])
elif scores["user"] < scores["app"]:
print(messages["app win game"])
else:
print(messages["same result"])
print(messages["bye"])
امیدارم آموزش خوبی براتون بوده باشه و کمکی جهت آشنایی بهتر با پایتون و همچنین برنامه نویسی شده باشه.
اگر ابهامی در هر کدام از قسمت های کد دارید در نظرات بفرمایید تا توضیح بیشتری بدهم.
ممنون میشم نظراتتون رو با من درمیون بزارید تا نقاط قوت و ضعف کار مشخص بشه تا بتونم محتواهای با کیفیت تری تولید کنم. برای من به عنوان نویسنده و برای شما به عنوان خواننده مفید باشه.
مطلبی دیگر از این انتشارات
ساخت یک بازی ریاضی ساده با پایتون
مطلبی دیگر در همین موضوع
در سال ۲۰۱۹ آیا هنوز jQuery زنده است؟
بر اساس علایق شما
ویرگولاوا! (از حرفایی که تو دلت پنهونه میترسم!)