Giter Site home page Giter Site logo

tagniam / turn Goto Github PK

View Code? Open in Web Editor NEW
59.0 59.0 75.0 2.84 MB

Hacktkober 'n' Slash (C++ turn-based RPG game)

License: MIT License

C++ 96.91% C 1.00% CMake 2.02% Shell 0.07%
beginner-friendly c-plus-plus cross-platform game hacktoberfest terminal-based

turn's People

Contributors

alissawe avatar asriram3 avatar bodand avatar boozec avatar chuck-sys avatar dj73 avatar eraymitrani avatar giorgiopiazza avatar guus1311 avatar hubikazak avatar iamvibhorsingh avatar igorsegallafa avatar ilimugur avatar jerbast avatar joealam avatar kevinmmurphy avatar lalocode avatar ldaw avatar mario51y1 avatar mego avatar neroburner avatar parrajustin avatar rmdern avatar sarthi92 avatar sdmg15 avatar shaedil avatar superto avatar t3ssellate avatar tagniam avatar tenosiswono avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

turn's Issues

Crop screenshots

The readme screenshots shouldn't show the Windows titlebars or scrollbars. There's also a weird red bar on the right of the battle screenshot that should also be cropped out.

Embed sound files in game executable

Currently we don't embed sounds in the game executable: the program expects a sounds folder in the same directory to play the sound files from. We'd like to change that, so that the sound files are embedded within the executable and would not require an external sounds folder.

The implementation should work across all platforms. One possible way to do this is to convert the sound files into byte array constants, but let me know of any other (possibly better) approaches!

Allow for names with spaces

On the first run, the user has to set the player name. Unfortunately the player name will not include characters after a space in the name. So if you enter John Doe as the player name, the name will be saved as John.

Create animated GIF of gameplay

GIFs are all the rage nowadays. It would be nice to showcase the game without having to build and run it locally, in the form of two gifs in the README:

  • One gif of gameplay in battle
  • One gif of gameplay in the store or gambling

Use potions and whetstones in between battles

Currently these items can only be used in battle. Ideally for extensibility these should be contained in a submenu on the intermission screen, i.e.:

1) Start Battle
2) Store
3) Gamble
4) Use Item
5) Quit
> 4

Display level up message

If the user levels up after a battle, show a message at the intermission screen congratulating the player.

Add new item type: molotov

We'd like to add a new item type, the molotov, which deals 30-40 damage on the first hit and an additional 5-10 damage for the next 2 turns. Additionally:

  • Every player should start with 1 molotov in the inventory.
  • It should be sold in the game store for 75 coins.
  • It should be able to be gambled for.
  • It should be documented in the game instructions.

Modernize random generation

In a lot of places, the project uses the C rand() function, even though the project itself is C++11, which has the "new" and fancy <random> header.
C++11 and up projects should always use <random> and one of its PRNGs instead of the severely limited C random functions, whose actual randomness is really platform-dependent and will work differently across libc implementations. Also using modulo to calculate a distribution skews the results. See this talk from STL, in which he describes why rand() is bad. (And also how to use the C++11 <random> header.)

I suggest a small random wrapper function be made that takes a min and max and generates a random number within those. Something like this:

int random_int(int min, int max) {
    static std::mt19937 rng(std::random_device{}());
    std::uniform_int_distribution<int> dist(min, max);

    return dist(rng);
}

And then use this function in all places where randomness is needed.

New player glitch

When a user plays the game for the first time, when they try to quit during intermission, the game goes back to battling.

unit testing

create unit testing for the project covering various classes .
maybe google mock

Format inventory screen

Right now the inventory looks like this.

*----------- INVENTORY -----------*
Level 2                 0/100 xp
| Arrows: [10]
| Potions: [0]
| Bombs: [3]
| Whetstones: [0]
| Weapon strength: [100%]
| Wealth: [48] coins
*---------------------------------*

3 things need to be implemented:

  1. Put a divider between the level/xp line and the items
  2. Draw a right side to the inventory box
  3. xp needs to be aligned to the right, with 1 space padding

So it would end up looking like this diagram, labelled:

*----------- INVENTORY -----------*
| Level 2                0/100 xp | <- 3
+---------------------------------+ <- 1
| Arrows: [10]                    |
| Potions: [0]                    |
| Bombs: [3]                      | <- 2
| Whetstones: [0]                 |
| Weapon strength: [100%]         | 
| Wealth: [48] coins              |
*---------------------------------*

You will have to do some character counting when implementing 2 and 3, since as the values add digits, less spaces will be needed.

Small game exit bug

To reproduce this bug, start the game and choose 2) How To Play, then 1) Quit, then 3) Quit. The game only quits once you choose 3 twice, when it should quit right away.

Cross-platform support

It should be possible to make this game cross-platform. This would require using a different build system (e.g. CMake), as well as replacing uses of the windows API. From a brief view, it appears that it's only used for:

  • console rendering
  • input (with _getch)
  • sleeping (easily replaceable with std::this_thread::sleep_for)

Console input/output could possibly be replaced with ncurses/pdcurses. Alternatively, ncurses could be used on Linux while still having windows API on windows with ifdef's.

Document player stats

In the README there should be a sub-section under How To Play called Player Classes. The documentation should follow this table template:

Name Attack Damage Risk Attack Damage Healing Amount
Player 1 10-15 20-25 10-15
Player 2 10-15 20-25 10-15

etc.

The Warrior, Rogue, Healer, Debugger, and Saitama player classes should be documented.
The attack/risk attack/healing points is documented in each player's corresponding cpp file.

Copy how to play into README

In Game.cpp there is a how to play blurb that should be copied into README.md. The ACTIONS and ITEMS sections shouldn't be copied since they're already in the readme.

Prevent player with no coins from gambling

See Gambling.cpp. Gambling can only occur when the player has at least the same amount of coins as CoinsDeduction. Check if the player has enough coins after GenerateValues() method is called. If they don't, return to the intermission menu.

Create RandomEvent helper function

Here is how we currently calculate random damage (from GiantCrab.cpp):

int GiantCrab::ReturnRiskAttackDamage() {
    int selector = Common::RandomInt(0, 5);
    switch(selector) {
    case 0:
    case 1:
    case 2:
    case 3:
        return 0;
        break;
    case 4:
    case 5:
        return 20;
        break;
    default:
        return 0;
        break;
    }
}

This basically means:

  • 4/6 chance of doing 0 damage
  • 2/6 chance of doing 20 damage

We'd like to create a helper method to avoid doing this. This is what I had in mind:

We'd have to create a function with the signature:

template<class T>
T RandomEvent(int denominator, vector<int> numerators, vector<T> outcomes)

where it must be that sum(numerators) == denominator and numerators.size() == outcomes.size(). The function takes in generic outcomes, so that even things like functions could be decided randomly.

With this helper function, the GiantCrab function could be rewritten as:

int GiantCrab::ReturnRiskAttackDamage() {
    // 4/6 chance of doing 0 damage
    // 2/6 chance of doing 20 damage

    int denominator = 6;
    vector<int> numerators{4, 2};
    vector<int> outcomes{0, 20};
    return RandomEvent<int>(denominator, numerators, outcomes);
}

This helper function should be placed in the Common class. If you have another design in mind, or know any existing STL libraries that can do this, let me know - we can probably do better than this ๐Ÿ˜›

Add item selling functionality

The game currently allows the player to buy items from Jeremy's Tool Store, but the player cannot sell any items from their inventory to the store. We'd like to implement selling functionality in Jeremy's Tool Store.

The player should be able to sell items at the same price they can be bought, for example since 1 bomb from the store costs 100 coins, the player should be able to sell 1 bomb from their invenyory for 100 coins.

Document enemy stats

In the README there should be a sub-section under How To Play called Enemy Types. The documentation should follow this table template:

Name Attack Damage Risk Attack Damage Healing Amount
Enemy 1 10-15 20-25 10-15
Enemy 2 10-15 20-25 10-15

etc.

The Crab, Giant Crab, Squid, Giant Squid, and Lich enemy classes should be documented.
The attack/risk attack/healing points is documented in each enemy's corresponding cpp file.

Notify player when using non-existent item

When a player attempts to use an item that is not in their inventory, currently the game doesn't do anything at all.

Instead, there should be a message displayed that the item is not in the player's inventory, then call Sleep(SLEEP_MS) and redraw the screen.

Add action sound effects

The game would be a lot more fun with audio. In-game sound effects will be needed when the player AND enemy does the following:

  • Attack
  • Risk Attack
  • Heal

Make sure to credit where you get the sound effects from in the source code and in the readme!

Make enemy notification more interesting

There could be variation in the " encountered!" message at the beginning of a battle to add flavour to the game.

If there's no objections, I'd like to implement this.

Fix Windows specific macro checks

The Windows macro checks check for _WINDOWS to be defined, however, as I checked it is not defined on any compiler I have installed (GCC 9.2; clang 8.0.1; MSVC 19.21.27702.2) that can target Windows. It is not even mentioned on MSDN.
To note, my setup couldn't compile the program as is; it thought I was on something non-windows, and tried to include <termios.h>.

Momentarily, I can do a pull request, to patch this, if it's alright.

Appendix
GCC & clang check:
pwsh_V97Zrm5qMv
MSVC check:
cmd_0XQp9nX0fZ

Add item sound effects

Edit: some sound effects are already implemented, like the sounds for attacking, bow and arrow attacks, and healing. However some sound effects are missing:

  • Potion
  • Bomb
  • Whetstone
  • Fleeing
  • Buying things in the store
  • Gambling

The game would be a lot more fun with audio. In-game sound effects will be needed when the player uses the following items:

* Potion
* Whetstone
* Arrow
* Bomb

Make sure to credit where you get the sound effects from in the readme!

Use compiler warnings

The use of compiler warnings is good practice and they should be enabled for all projects. On GCC and Clang -Wall, -Wextra, and -Wpedantic should be enabled, while /W3 on MSVC.

With this, multiple warnings are generated when compiling:
MSCV:

  • C4530: Basically an MSVC-specific warning that one should add /EHsc to the compile flags. This is a simple CMake script fix.

GCC:

  • -Wmisleading-indentation: In Player.cpp there are a few else cases where the following line is indented with a tab. This is not really a misleading indentation problem and is mostly just a false positive on the compiler's part, but that tab should really be a set of spaces since that function is mostly indented with spaces. (Also the whole project's is completely mixed on tabs vs spaces. IMO as a separate issue this should be fixed.)
  • -Wunused-variable: Player.cpp:539 defines int countLength = 0; which is not used anywhere and should be deleted.

Clang:

  • -Winconsistent-missing-override: Descendants of the Enemy class seem to override virtual member functions such as GetIntro() and others like ReturnDamage() which come from Entity. These functions should be marked override but they are not. I guess the compiler figures out what you wanted to do, but this is really bad practice. Note that this is triggered even if one passes no arguments to clang while compiling, as in this is a default warning.
  • -Wunused-private-field: The Game class's _Level member is not used anywhere and should be deleted. (Also, identifiers starting with an underscore and then an upper case character (like _Level, or _Player) are reserved for implementations, and using them is undefined behavior)
  • -Wreorder-ctor: The member initializer list of SoundMaker class initializes members out of order. This is, iirc, UB, but most certainly nothing fun. Lines 77 and 76 should be swapped.

I can make a PR with these fixes if it is going to be considered.

Make exiting consistent

0 should be the default menu option for exiting the current menu.

For example, the main menu has option 3) Exit, which should be changed to 0) Exit, and the intermission screen has 5) Exit which should be changed to 0) Exit.

This ensures consistency in the game options.

Let player choose gender

It would be nice to let the player choose their gender when creating the character. Then, the correct pronouns should be used in battles etc. in order to improve immersion.

"He/his" pronoun is currently used in:

  • Generic Attack
  • Bow and Arrow
  • Use Item

Implement an in-game store

This one should be fun!

What use are coins without things to buy? Using their coins, the player should be able to buy the items they need for battle in this store.

The price breakdown for the items should be as follows:

  • 5 Arrows: 25 coins
  • 1 Bomb: 100 coins
  • 1 Potion: 150 coins
  • 1 whetstone: 20 coins

In terms of the code, all the store functionality should be written inside Store.cpp. The player object is already passed in to the StoreFront() method as a starting point.

Change menu option number

In the gambling menu, the option to pass and go back to the intermission menu is 3).

1) Reveal Die
2) Shake Die
3) Pass

We'd like to change it to 0), to be consistent with the rest of the game's menus:

1) Reveal Die
2) Shake Die
0) Pass

Health not visible when <50%

As I was playing the game, I found it slightly frustrating that I wasn't able to see my health nor my enemy's. Below is what I mean.
healthbarold

I looked over the code, especially Entity.cpp, Console.h and Console.cpp and changed the background of the white part of the health bar to a dark grey.
healthbar

Serialize/deserialize player data to/from JSON

Currently we save player data by writing raw values line-by-line in data.txt. It looks something like this:

1
Dude
M
11
10
89
35
2
9
18
78
401

We'd like to change the player data parsing code so that it supports reading from and writing to data.txt in JSON format, which should be changed to look something like this:

{
    "player_type": 1,
    "name": "Dude",
    "gender": "M",
    "level": 11,
    "experience": 10,
    "health": 89,
    "arrows": 35,
    "bombs": 2,
    "potions": 9,
    "whetstones": 18,
    "weaponstrength": 78,
    "coins": 401
}

This way it is much clearer what the player's attributes are by looking at data.txt.

Feel free to use a JSON parsing library, though preferably it should be lightweight and header-only!

Make your own enemy types

Spice up the game by creating your own enemy types (even if you can't/don't want to program, see below). Feel free to be creative! Here are some examples you could implement:

  • Zombies
  • Goblins
  • Gargoyles
  • Leprechauns
  • etc...

See #33 for an example of how to do it. You'll have to create a new class that extends the Enemy class, and change Game::SetEnemy() to make that class available during the random enemy generation. This is all done well in the example (thanks @RMDern!)


If you don't know how to program something like this, you can still contribute.

  1. Add your enemy type to the enemy types table in the wiki with all details
  2. Create a new issue with the title "Implement [enemy name here]"
  3. Tag issue with the hacktoberfest and help wanted labels
  4. Put a description saying to look in the wiki for your enemy type

Write shop greeting messages

Every good RPG has shops with random greeting messages. This RPG is no different.

Jeremy's Tools Store needs random greeting messages to display whenever the player enters the store. Print the greeting right after the shop title.

For example:

 Jeremy's Tools Store
 "Buy somethin', would ya?"

 ----ITEM----------------COST------ 

 1) Arrows x 5		 200
 2) Bomb		 100

Make as many greetings as you'd like. Make sure they add a little personality to the game!

Do something with CMake's GLOB_RECURSE

As stated in the CMake docs, it is unwise to use GLOB_RECURSE to find source files.
And even worse if used as here, without CONFIGURE_DEPENDS, which should fix the problem of calling make ending up not recompiling some changed files.

I suggest adding at least CONFIGURE_DEPENDS, but it'd be better to add each file separately and manually when added to the project.

The latter requires some community approval, therefore, I wasn't planning on creating a PR until it is discussed which route to take if one is even taken.

Refactor Player::AddToInventory

Current, Player::AddToInventory(vector<int> drops) adds items to the player's inventory by checking drops[0] for the number of arrows to add, drops[1] for bombs, drops[2] for potions, etc.

We'd like to refactor this such that the method takes a vector of std::pair<ITEMTYPE, int>, where the first element in the pair is the type of the item to add and the second element in the pair is the amount to add.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.