ساخت بازی سنگ، کاغذ، قیچی با پایتون

در این مطلب قصد دارم شما رو با پایتون بیشتر آشنا کنم و با هم بازی خاطره انگیز سنگ، کاغذ، قیچی رو بنویسم. امیدوارم در این چند دقیقه ای که با هم هستیم لحظات خوشی داشته باشیم.

پیش نیاز

  • آشنایی با پایتون به صورت مقدماتی

توضیحی در رابطه با بازی

بازی به صورت چند زبانه طراحی شده است.

همچنین در هر تعامل، کاربر امکان خروج از بازی را دارد.

مراجل بازی:

  • کاربر زبان مورد نظر خود را انتخاب می کند.
  • کاربر امکان انتخاب تعداد دست بازی را دارد. می تواند نامحدود نیز باشد.
  • کاربر از بین سنگ، کاغذ، قیچی یکی را انتخاب می کند.
  • اپلیکیشن به صورت رندوم برای خود از موارد یکی را انتخاب می کند و سپس نتیجه را اعلام می کند

پرسه بالا تا زمان به اتمام رسیدن تعداد دست های بازی یا خارج شدن کاربر ادامه پیدا می کند.

  • پس از اتمام بازی خلاصه ای از وضعیت بازی که شامل تعداد دست بازی شده، تعداد بردهای کاربر، تعداد برد های اپلیکیشن، تعداد مساوی ها و همچنین برنده نهایی بازی نمایش داده می شود.

جهت مشاهده ویدیو خروجی بازی در آپارات کلیک کنید

قدم به قدم پیش می رویم

به دلیل اینکه بهتر با طرز تفکر نحوه کد نویسی برای انجام یک پروژه آشنا شوید کد به صورت خط به خط نوشته نمی شود و ممکن است نیاز باشد به خط های بالاتر کدی اضافه شود یا تغییر کند. چون در واقعیت امر به این شکل است که با توجه به طرز تفکر برنامه نویس و پیشبرد کار کد ها اصلاح می شود و به این صورت نیست که از ابتدا تا انتها یک دست کد ها نوشته شود. البته که با افزایش مهارت و انجام تمرین بیشتر به این سمت پیش خواهید رفت که بدانید در چند خط آینده چه خواهید نوشت پس پیش نیاز آن را نیز می نویسید که نیاز به بازگشت و اصلاح کد های قبلی نباشد.

شروع کد نویسی

سورس کد به صورت یکجا در انتهای پست قرار دارد.

در ابتدا متغییری از نوع دیکشنری با نام messagesInAllLanguages تعریف می کنیم که حاوی پیام ها و سوالاتی است که برای تعامل با کاربر به آن ها نیاز داریم. از آن جایی که این بازی چند زبانه است به صورت ساختاری که زبان ها در کلید متغییر قرار می گیرند و جملات در مقدار آن تعریف می شود.

با توجه به ساختار زیر که جملات برای زبان انگلیسی و اسپانیایی نوشته شده است به راحت می توانید گسترش دهید و زبان های دیگر را نیز به آن اضافه کنید. فقط کافی است مقادیر کلید هر عنوان را ترجمه کنید.

messagesInAllLanguages = {
    &quoten&quot: {
        &quotwelcome&quot: &quotWelcome to the game&quot,
        &quotchoose language&quot: &quotPlease choose your language en, es, (q to exit): &quot,
        &quotchoose action&quot: &quotPlease choose between stone(st), paper(pa), scissors(sc) (q to exit): &quot,
        &quotbye&quot: &quotWe're glad you used our game. hope to see you again&quot,
        &quotuser score&quot: &quotYour score: {0}&quot,
        &quotapp score&quot: &quotApp's score: {0}&quot,
        &quotequal round&quot: &quotequal round: {0}&quot,
        &quotequal rounds&quot: &quotequal rounds: {0}&quot,
        &quotsame action&quot: &quotwhoops! you and app select the same&quot,
        &quotapp win round&quot: &quotApp wins round&quot,
        &quotuser win round&quot: &quotYou win round&quot,
        &quotapp win game&quot: &quotApp wins game&quot,
        &quotuser win game&quot: &quotYou win game&quot,
        &quotsame result&quot: &quotWhoops! you and app has the same score&quot,
        &quotapp chosen&quot: &quotApp chosen: {0}&quot,
        &quotgame round&quot: &quotHow many rounds do you want to play (-1 for unlimited)? (q to exit) &quot,
        &quotplay round&quot: &quotYou play 1 round&quot,
        &quotplay rounds&quot: &quotYou play {0} rounds&quot,
    },
    &quotes&quot: {
        &quotwelcome&quot: &quotBienvenida al juego&quot,
        &quotchoose language&quot: &quotElija su idioma en, es, (q para salir): &quot,
        &quotchoose action&quot: &quotElija entre piedra(pi), papel(pa), tijeras(ti) (q para salir): &quot,
        &quotbye&quot: &quotNos alegra que hayas usado nuestro juego. espero verte de nuevo&quot,
        &quotuser score&quot: &quotTu puntuación: {0}&quot,
        &quotapp score&quot: &quotPuntuación de la aplicación: {0}&quot,
        &quotequal round&quot: &quotronda igual: {0}&quot,
        &quotequal rounds&quot: &quotrondas iguales: {0}&quot,
        &quotsame action&quot: &quot¡Ups! dusted y la aplicación seleccionan lo mismo&quot,
        &quotapp win round&quot: &quotLa aplicación gana ronda&quot,
        &quotuser win round&quot: &quotTu ganas ronda&quot,
        &quotapp win game&quot: &quotLa aplicación gana el juego&quot,
        &quotuser win game&quot: &quotTu ganas el juego&quot,
        &quotsame result&quot: &quot¡Ups! tú y la aplicación tienen la misma puntuación&quot,
        &quotapp chosen&quot: &quotAplicación elegida: {0}&quot,
        &quotgame round&quot: &quot¿Cuántas rondas quieres jugar (-1 para ilimitado)? (q para salir) &quot,
        &quotplay round&quot: &quotTu juegas 1 ronda&quot,
        &quotplay rounds&quot: &quotJuegas {0} rondas&quot,
    }
}


در ابتدا متغییری با نام languages از نوع لیست تعریف می کنیم که دارای کلید های متغییر messagesInAllLanguages است که مقدار آن نام زبان های بازی می شود.

languages = list(messagesInAllLanguages.keys())


متغیری با نام language تعریف می کنیم و به صورت پیشفرض زبان را روی en قرار می دهیم.

language = &quoten&quot


متغییری با نام quitApp تعریف می کنیم که مقدار اولیه False دارد و با توجه به اسم آن مشخص کننده نگهدارنده وضعیت خروج از بازی است که بعدا با ورودی که از کاربر گرفته می شود در صورت نیاز True می شود.

quitApp = False


در یک while اقدام به پرسیدن زبان بازی از کاربر می کنیم به این دلیل که اگر به درستی پاسخ نداد آن قدر این پرسه تکرار شود تا پاسخ مورد انتظار ما دریافت شود.

پرسش انتخاب زبان را از کاربر می پرسیم و در متغییر language نگه داری می کنیم. آن را به حروف کوچک تبدیل می کنیم. با انجام این کار، امکان این که کاربر با حرف بزرگ و یا ترکیبی وارد کند را داده ایم. می تواند در تعامل با کاربر حس خوبی به وجود آورد.

while True:
     language = input(messagesInAllLanguages[&quoten&quot][&quotchoose language&quot])
     language = language.lower()


بررسی می کنیم که اگر زبان وارد شده کاربر جز زبان های بازی بود لوپ را بشکند و بازی به جریان خود ادامه دهد.

if language in languages:
         break


در غیر اینصورت بررسی می کنیم که اگر کاربر q را به جهت خروج وارد کرده است لوپ بشکند و ادامه روند پیش برد. نکته قابل توجه این که چون کاربر در پاسخ پرسش q وارد کرده است و مقدار را در language ریخته ایم دوباره به صورت پیشفرض en را قرار می دهیم و مقدار متغییر quitApp را نیز برابر True قرار می دهیم.

    if language == &quotq&quot:
        language = &quoten&quot
        quitApp = True
        break

اگر هیچ کدام از حالت های بالا رخ ندهد یعنی کاربر زبان درستی را وارد نکرده است که باعث می شود while به کار خود ادامه دهد و روند بالا از اول تکرار شود.


در قسمت قبل زبان بازی مشخص شده و با استفاده از آن پیام های زبان مورد نظر را در متغییر messages قرار می دهیم.

messages = messagesInAllLanguages[language]


سپس دو متغییر originalGameRound و gameRoundRemind که به ترتیب نگه دارنده تعداد دست انتخاب شده توسط کاربر و تعداد دست باقی مانده از بازی هستند که به صورت پیشفرض 0 مقدار دهی می شوند.

originalGameRound = gameRoundRemind = 0


پیام خوش آمد گویی به کاربر نمایش داده می شود.

print(messages[&quotwelcome&quot])


در while اقدام به پرسش از کاربر جهت دریافت تعداد دست هایی که میخواهد بازی کند می کنیم و مقدار را در متغییر gameRoundRemind ذخیره می کنیم.

while not quitApp:
      gameRoundRemind = input(messages[&quotgame round&quot])


بررسی میکنیم که اگر مقدار q را جهت خروج از بازی وارد کرده است لوپ شکسته شود و مقدار متغییر quitApp را True قرار می دهیم.

    if gameRoundRemind == &quotq&quot:
            quitApp = True         
             break


بررسی می کنیم که اگر مقدار دریافت شده از کاربر عددی نباشد و -1 نیز نباشد (-1 برای دست نامحدود است) لوپ کار خود از ابتدا شروع کند.

    if not gameRoundRemind.isdecimal() and gameRoundRemind != &quot-1&quot:
             continue


اگر اتفاق بالا نیفتاد پس ورودی کاربر صحیح است و مقدار دریافتی از کاربر را به نوع عدد تبدیل می کنیم و سپس آن را در متغییر های gameRoundRemind و originalGameRound که از قبل تعریف کرده ایم قرار می دهیم.

    gameRoundRemind = originalGameRound = int(gameRoundRemind)


با استفاده از کلمه کلیدی break لوپ را می شکنیم که روند بازی ادامه پیدا کند.

    break


در ادامه مقادیر سنگ، کاغذ، قیچی را با توجه به زبان های بازی تعریف می کنیم و در کلید long در هر زبان قرار می دهیم اگر توجه کنید برای هر مقدار یک کلید wins against تعریف کرده ایم که نشان دهنده این است که در مقابل چه چیزی برنده است. به عنوان مثال: سنگ در مقابل قیچی برنده می شود پس مقدار آن کلید برابر با قیچی است.
کلید short در هر زبان نشان دهنده مخفف ها است که به عنوان مثل کاربر به جای وارد کردن stone از st استفاده می کند که در بازی با استفاده از مقادیر short آن را با مقدار کامل خود جایگزین می کنیم.
در ادامه که از این دیکشنری استفاده کنیم بهتر این توضیحات را درک خواهید کرد.

actionsDetails = {
    &quoten&quot: {
        &quotshort&quot: {
            &quotst&quot: &quotstone&quot,
            &quotpa&quot: &quotpaper&quot,
            &quotsc&quot: &quotscissors&quot,
        },
        &quotlong&quot: {
            &quotstone&quot: {
                &quotwins against&quot: [&quotscissors&quot]
            },
            &quotpaper&quot: {
                &quotwins against&quot: [&quotstone&quot]
            },
            &quotscissors&quot: {
                &quotwins against&quot: [&quotpaper&quot]
            }
        }
    },
    &quotes&quot: {
        &quotshort&quot: {
            &quotpi&quot: &quotpiedra&quot,
            &quotpa&quot: &quotpapel&quot,
            &quotti&quot: &quottijeras&quot,
        },
        &quotlong&quot: {
            &quotpiedra&quot: {
                &quotwins against&quot: [&quottijeras&quot]
            },
            &quotpapel&quot: {
                &quotwins against&quot: [&quotpiedra&quot]
            },
            &quottijeras&quot: {
                &quotwins against&quot: [&quotpapel&quot]
            }
        }
    }
}


در دو متغییر actionsLong و actionsShort، همانطور که از نام آن ها مشخص است با توجه به زبان انتخاب شده مقادیر short و long را در آن نگه داری می کنیم.

actionsLong = list(actionsDetails[language][&quotlong&quot].keys()) actionsShort = actionsDetails[language][&quotshort&quot]


در ادامه در while با کاربر تعامل میکنیم و بازی شروع می شود.

متغییری با نام scores از نوع دیکشنری تعریف می کنیم که امتیاز کاربر و بازی را در خود نگه داری می کند.

scores = {&quotuser&quot: 0, &quotapp&quot: 0}


در تعامل با کاربر گزینه مورد نظر او از میان سنگ، کاغذ و قیچی را دریافت می کنیم. در متغییر action مقادیر انتخاب شده کاربر و بازی (به صورت رندم) را نگه داری می کنیم. مقدار دریافت شده از کاربر را به حروف کوچک تبدیل می کنیم.

while gameRoundRemind != 0:
     action = {
         &quotuser&quot: input(messages[&quotchoose action&quot]),
         &quotapp&quot: random.choice(actionsLong)
     }
     action[&quotuser&quot] = action[&quotuser&quot].lower()


بررسی میکنیم که اگر کابر q را جهت خروج انتخاب کرده است لوپ بشکند و روند بازی ادامه پیدا کند.

    if action[&quotuser&quot] == &quotq&quot:
         quitApp = True
         break


گر کاربر مقدار مخفف را وارد کرده باشد به مقدار اصلی تبدیل کنیم.

    longFromShort = actionsShort.get(action[&quotuser&quot])
    if longFromShort:
        action[&quotuser&quot] = longFromShort


اگر مقدار وارد شده کاربر صحیح نباشد لوپ از اول اجرا می شود و پروسه بالا تکرار می شود.

    if action[&quotuser&quot] not in actionsLong:
         continue


جهت جدا شدن پیغام ها از سوالات تعداد * چاپ می کنیم. مقدار انتخاب شده توسط سیستم به کاربر نمایش داده می شود.

    print(&quot*&quot * 40)
    print(messages[&quotapp chosen&quot].format(action[&quotapp&quot]))


بررسی می شود که اگر مقدار انتخابی کاربر و سیستم یکی باشد اقدامی صورت نگیرد و صرفا پیغامی جهت این مورد به کاربر نمایش داده می شود.

اگر مقدار وارد شده کاربر جز لیست برندگان مورد انتخاب سیستم باشد، پس سیستم برنده است و به امتیاز او اضافه می کنیم و پیغام مناسب نمایش داده می شود.

در غیر اینصورت کاربر برنده است و به امتیاز او اضافه می کنیم و پیغام نمایش داده می شود.

     if action[&quotuser&quot] == action[&quotapp&quot]:
        print(messages[&quotsame action&quot])
    elif action[&quotuser&quot] in actionsDetails[language][&quotlong&quot][action[&quotapp&quot]][&quotwins against&quot]:
        scores[&quotapp&quot] += 1
        print(messages[&quotapp win round&quot])
    else:
        scores[&quotuser&quot] += 1
        print(messages[&quotuser win round&quot])


در انتها از مقدار دست های بازی یکی کم می شود و پروسه بالا تا انتهای بازی ادامه پیدا می کند.

     print(&quot*&quot * 40)
     gameRoundRemind -= 1


با بررسی شرط زیر متوجه می شویم که کاربر بازی انجام داده است یا خیر. و کد های بعد از آن در صورت True بودن شرط اجرا می شود.

if originalGameRound != gameRoundRemind:


محاسبه می کنیم که چند دست بازی انجام شده است.

gameRoundPlayed = originalGameRound - gameRoundRemind


تعداد دست های بازی شده را نمایش می دهیم. اگر یک بازی انجام شده باشد داخل if اجرا می شود و در غیر اینصورت else

     if (originalGameRound - 1) == gameRoundRemind:
         print(messages[&quotplay round&quot])
     else:
         print(messages[&quotplay rounds&quot].format(originalGameRound - gameRoundRemind))


تعداد برد های کاربر و سیستم را نمایش می دهیم.

     print(messages[&quotuser score&quot].format(scores[&quotuser&quot]))
     print(messages[&quotapp score&quot].format(scores[&quotapp&quot]))


تعداد مساوی ها را محاسبه می کنیم و بررسی می کنیم اگر بیشتر از 0 است نمایش داده شود.

اگر برابر 1 است داخل if در غیر اینصورت else اجرا می شود.

     equal = gameRoundPlayed - (scores[&quotuser&quot] + scores[&quotapp&quot])
     if equal == 1:
         print(messages[&quotequal round&quot].format(equal))
     elif equal > 1:
         print(messages[&quotequal rounds&quot].format(equal))


با توجه به وضعیت بازی که کاربر یا سیستم برنده شده است و یا مساوی شده اند پیغام مناسب نمایش داده می شود.

     if scores[&quotuser&quot] > scores[&quotapp&quot]:
         print(messages[&quotuser win game&quot])
     elif scores[&quotuser&quot] < scores[&quotapp&quot]:
         print(messages[&quotapp win game&quot])
     else:
         print(messages[&quotsame result&quot])


در انتهای بازی هم پیغام خداحافظی نمایش می دهیم!

print(messages[&quotbye&quot])


کد نهایی به صورت زیر خواهد بود

جهت دانلود کد کلیک کنید

import random

messagesInAllLanguages = {
    &quoten&quot: {
        &quotwelcome&quot: &quotWelcome to the game&quot,
        &quotchoose language&quot: &quotPlease choose your language en, es, (q to exit): &quot,
        &quotchoose action&quot: &quotPlease choose between stone(st), paper(pa), scissors(sc) (q to exit): &quot,
        &quotbye&quot: &quotWe're glad you used our game. hope to see you again&quot,
        &quotuser score&quot: &quotYour score: {0}&quot,
        &quotapp score&quot: &quotApp's score: {0}&quot,
        &quotequal round&quot: &quotequal round: {0}&quot,
        &quotequal rounds&quot: &quotequal rounds: {0}&quot,
        &quotsame action&quot: &quotwhoops! you and app select the same&quot,
        &quotapp win round&quot: &quotApp wins round&quot,
        &quotuser win round&quot: &quotYou win round&quot,
        &quotapp win game&quot: &quotApp wins game&quot,
        &quotuser win game&quot: &quotYou win game&quot,
        &quotsame result&quot: &quotWhoops! you and app has the same score&quot,
        &quotapp chosen&quot: &quotApp chosen: {0}&quot,
        &quotgame round&quot: &quotHow many rounds do you want to play (-1 for unlimited)? (q to exit) &quot,
        &quotplay round&quot: &quotYou play 1 round&quot,
        &quotplay rounds&quot: &quotYou play {0} rounds&quot,
    },
    &quotes&quot: {
        &quotwelcome&quot: &quotBienvenida al juego&quot,
        &quotchoose language&quot: &quotElija su idioma en, es, (q para salir): &quot,
        &quotchoose action&quot: &quotElija entre piedra(pi), papel(pa), tijeras(ti) (q para salir): &quot,
        &quotbye&quot: &quotNos alegra que hayas usado nuestro juego. espero verte de nuevo&quot,
        &quotuser score&quot: &quotTu puntuación: {0}&quot,
        &quotapp score&quot: &quotPuntuación de la aplicación: {0}&quot,
        &quotequal round&quot: &quotronda igual: {0}&quot,
        &quotequal rounds&quot: &quotrondas iguales: {0}&quot,
        &quotsame action&quot: &quot¡Ups! dusted y la aplicación seleccionan lo mismo&quot,
        &quotapp win round&quot: &quotLa aplicación gana ronda&quot,
        &quotuser win round&quot: &quotTu ganas ronda&quot,
        &quotapp win game&quot: &quotLa aplicación gana el juego&quot,
        &quotuser win game&quot: &quotTu ganas el juego&quot,
        &quotsame result&quot: &quot¡Ups! tú y la aplicación tienen la misma puntuación&quot,
        &quotapp chosen&quot: &quotAplicación elegida: {0}&quot,
        &quotgame round&quot: &quot¿Cuántas rondas quieres jugar (-1 para ilimitado)? (q para salir) &quot,
        &quotplay round&quot: &quotTu juegas 1 ronda&quot,
        &quotplay rounds&quot: &quotJuegas {0} rondas&quot,
    }
}
languages = list(messagesInAllLanguages.keys())
language = &quoten&quot
quitApp = False

while True:
    language = input(messagesInAllLanguages[&quoten&quot][&quotchoose language&quot])
    language = language.lower()

    if language in languages:
        break

    if language == &quotq&quot:
        language = &quoten&quot
        quitApp = True
        break

messages = messagesInAllLanguages[language]
originalGameRound = gameRoundRemind = 0
print(messages[&quotwelcome&quot])

while not quitApp:

    gameRoundRemind = input(messages[&quotgame round&quot])

    if gameRoundRemind == &quotq&quot:
        quitApp = True
        break

    if not gameRoundRemind.isdecimal() and gameRoundRemind != &quot-1&quot:
        continue

    gameRoundRemind = originalGameRound = int(gameRoundRemind)

    break

actionsDetails = {
    &quoten&quot: {
        &quotshort&quot: {
            &quotst&quot: &quotstone&quot,
            &quotpa&quot: &quotpaper&quot,
            &quotsc&quot: &quotscissors&quot,
        },
        &quotlong&quot: {
            &quotstone&quot: {
                &quotwins against&quot: [&quotscissors&quot]
            },
            &quotpaper&quot: {
                &quotwins against&quot: [&quotstone&quot]
            },
            &quotscissors&quot: {
                &quotwins against&quot: [&quotpaper&quot]
            }
        }
    },
    &quotes&quot: {
        &quotshort&quot: {
            &quotpi&quot: &quotpiedra&quot,
            &quotpa&quot: &quotpapel&quot,
            &quotti&quot: &quottijeras&quot,
        },
        &quotlong&quot: {
            &quotpiedra&quot: {
                &quotwins against&quot: [&quottijeras&quot]
            },
            &quotpapel&quot: {
                &quotwins against&quot: [&quotpiedra&quot]
            },
            &quottijeras&quot: {
                &quotwins against&quot: [&quotpapel&quot]
            }
        }
    }
}
actionsLong = list(actionsDetails[language][&quotlong&quot].keys())
actionsShort = actionsDetails[language][&quotshort&quot]
scores = {&quotuser&quot: 0, &quotapp&quot: 0}

while gameRoundRemind != 0:
    action = {
        &quotuser&quot: input(messages[&quotchoose action&quot]),
        &quotapp&quot: random.choice(actionsLong)
    }
    action[&quotuser&quot] = action[&quotuser&quot].lower()

    if action[&quotuser&quot] == &quotq&quot:
        quitApp = True
        break

    longFromShort = actionsShort.get(action[&quotuser&quot])
    if longFromShort:
        action[&quotuser&quot] = longFromShort

    if action[&quotuser&quot] not in actionsLong:
        continue

    print(&quot*&quot * 40)
    print(messages[&quotapp chosen&quot].format(action[&quotapp&quot]))

    if action[&quotuser&quot] == action[&quotapp&quot]:
        print(messages[&quotsame action&quot])
    elif action[&quotuser&quot] in actionsDetails[language][&quotlong&quot][action[&quotapp&quot]][&quotwins against&quot]:
        scores[&quotapp&quot] += 1
        print(messages[&quotapp win round&quot])
    else:
        scores[&quotuser&quot] += 1
        print(messages[&quotuser win round&quot])

    print(&quot*&quot * 40)
    gameRoundRemind -= 1

if originalGameRound != gameRoundRemind:
    gameRoundPlayed = originalGameRound - gameRoundRemind

    if (originalGameRound - 1) == gameRoundRemind:
        print(messages[&quotplay round&quot])
    else:
        print(messages[&quotplay rounds&quot].format(originalGameRound - gameRoundRemind))

    print(messages[&quotuser score&quot].format(scores[&quotuser&quot]))
    print(messages[&quotapp score&quot].format(scores[&quotapp&quot]))
    equal = gameRoundPlayed - (scores[&quotuser&quot] + scores[&quotapp&quot])

    if equal == 1:
        print(messages[&quotequal round&quot].format(equal))
    elif equal > 1:
        print(messages[&quotequal rounds&quot].format(equal))

    if scores[&quotuser&quot] > scores[&quotapp&quot]:
        print(messages[&quotuser win game&quot])
    elif scores[&quotuser&quot] < scores[&quotapp&quot]:
        print(messages[&quotapp win game&quot])
    else:
        print(messages[&quotsame result&quot])

print(messages[&quotbye&quot])


امیدارم آموزش خوبی براتون بوده باشه و کمکی جهت آشنایی بهتر با پایتون و همچنین برنامه نویسی شده باشه.

اگر ابهامی در هر کدام از قسمت های کد دارید در نظرات بفرمایید تا توضیح بیشتری بدهم.

ممنون میشم نظراتتون رو با من درمیون بزارید تا نقاط قوت و ضعف کار مشخص بشه تا بتونم محتواهای با کیفیت تری تولید کنم. برای من به عنوان نویسنده و برای شما به عنوان خواننده مفید باشه.