Open mbg opened 4 years ago
If we are 'recreating' hearthstone (to some extent), we could have a set of different players/characters to pick from, which each have dedicated decks.
Maybe slightly dull, but the players could be programming languages. allowing for functional languages to be overpowered. Potentially functional languages could have a C'Thun-esque Monad card, and the Java deck could be 80% curly bracket minions
I think it would be a good idea to have FromJSON
and ToJSON
instances for the Deck
type (and by extension we'd probably need it for the Card
type), then users can save their decks as JSON files, and if we were using an API we'd likely use JSON to send decks also
Makes sense, although I suspect that a Deck
type might just be something like type Deck = [Card]
so it is really only the Card
type that we would need to worry about since instance FromJSON a => FromJSON [a]
already exists.
@GLynch-code that's a very cool idea!
You could have a pool of "OOP" cards and "FP" cards that relevant languages could draw from, and maybe each language has a special passive ability?
Maybe Python's special ability is that it can include cards from both OOP and FP 😛
@dixonary That sounds a good idea, so like a base deck of the main paradigms, then 'expansion' decks of the specific languages. Due to timescale on this, for now we might just want to focus on base and a first expansion, but in the future you could release updated expansion relevant to any major changes that occurred with the language, for example the adaption of pattern matching.
My hearthstone is a little rusty, but for those expansion we could try and recreate the quests in hearthstone.
For example, for the java expansion we could recreate the Murloc Quest, playing 10 curly brackets fills your hand with syntax along with a try catch. Or it could be adapted for Haskell, 10 binds results in do notation etc, that sort of thing. To be honest most of the ideas are transferable. Ill look into the quests a bit more and post what I find back here.
I think from the discussion on the Slack, we want the following basic rule set:
Keegan also provided some good example cards which can fit into particular paradigms.
To extend the cards/decks further
A deck would be a mix of base deck and expansion deck cards
So base decks could be OOP, Functional, Sequential (as examples) then expansion decks could be Java, Haskell, Python
Ideas for Specific Expansion sets (collected from the slack): C-thun-esque set, cards build up the 'strength' of a character over time Java expansion consists of curly bracket minions @keegan Scripts - These are cards with an Attack and HP value, that can be played onto the field Spells - Have no HP or Attack, affects existing cards according to the description Error - Cannot be played directly, cause negative effects while remaining in your hand Applicative - The specified effect is applied to all cards in hand/ on field Runtime Error - Cannot be played directly, reduces the number of available lambdas (mana) per turn by 1. IO - Has a 75% chance to 'upgrade' a card, increasing its stats, but a 25% chance to reduce it to a Runtime Error
= - Combines the effects of two cards into one. Removes any Errors. Foldr - Starting from the right, compresses all of your current cards on the field into a single card with all stats combined. Maybe - Attacks the right target 50% of the time. Otherwise, chooses between all available targets Monad Transformer - Convert all of the cards on your field into instances of Maybe. Binary Tree - Whenever this card is targeted, allow it to react first Hashmap - Summon a specified card from your deck Spaghetti Code - A low cost, low damage and low health card. Not the best, but does the job Waffles - Replace all cards on the field with Spaghetti Code Summoning Circle - Banish any non-Pure type card into Exile. Exiled cards are permanently removed from the game
What are the properties of each of the 3 card types, then we can implement the structures.
I believe all of them have a name, description, paradigm and program (their affects/what they do), then each card type will possibly have some extra things, but I don't know about the specifics
Programs will need attack, health and cost Scripts will need cost Errors won't need anything, i guess?
Thinking of errors as types, i was thinking data Error = Program | Event/Scripts So for example, you cast a script, and then if it fails (because programming language is impure), then a Program or Script is played against you.
Also it might be worth implementing different types of scripts as a type, so like DamageScript, HealScript, that sort of thing. As some might regenerate health whereas some might do damage. Maybe its worth just sticking to those two types for the moment?
I think that the idea is the card text should describe the effect that each script has - different scripts will have different effects, and they might be combined, eg. one script might hurt the enemy and heal you.
With the errors, is it that they can only be removed by another card that has 'remove an error' or something like that or will they have a specific kind of requirement to remove? If it is the latter then they may need to keep track of the requirement?
So as far as I can tell these is the properties needed for each type of card:
Program | Script/ |
Error |
---|---|---|
Name | Name | Name |
Description | Description | Description |
Paradigm | Paradigm | Paradigm |
Program | Program | Program |
Cost | Cost | |
Attack | ||
Health |
We could have something like some scripts can remove all errors of a certain paradigm(s), that would just require a [Paradigm]
field for scripts.
I'm not sure if we're calling them scripts or events
I'm assuming Cost/Attack/Health will be automatically generated from Program
? Not sure though
If I've missed anything point it out and I'll edit this. If no one else wants it I'll open a PR and have a go
Im not sure on Program for Script/Event. Maybe we could define a type Action = Heal Int | Attack Int to determine what a Script does. Then we could just use [Action] for Scripts which have multiple effects And I think we should just call them Scripts, I think that's been mutually agreed over time, maybe?
And id be happy to start working on these, I feel this might be one of the things in the project I could actually program...... maybe that is yet to be seen lol
So Program
is a list of instructions, I presumed that included attack and heal, maybe not though
And go for it, just to warn you when you change the definitions app/Main.hs
will probably chuck out a load of errors
Oh i see, i missed that somehow. Maybe we should change the name of the Program (minion) and Program ([Instruction]) to avoid confusion.
We could rename [Instr]
from Program
to Action
as its the action the card performs?
Action sounds fine to me. Also will we need a data type to represent the board (or the whole battle in general) when playing which can store information about each player's deck, board space, hand, dead programs (and anything else I am forgetting).
Maybe its worth having a Player data type, which stores what you said, and then having the board store the two current players?
Yeah that would make more sense. I would be willing to try program this, and some of the functions that would be needed to play, tomorrow, though I might need some help with things like randomising the deck as I haven't done random numbers in Haskell before.
This is useful, shuffleM
or shuffle'
should do exactly what you need, depending on whether you're in the IO
monad or not at that point, you can work out with @GLynch-code exactly whose doing what
If im interpreting this correctly @oscar-h64 , the scripts could just be represented by Name, Description, Paradigm, [Action] and Cost Errors would have cost 0, then since Action = [Instr], ive defined Instr = Attack Int | Heal Int. so that should cover heal and attack on your original table.
However im not sure how we could extend this to also be a Program too, To distinguish between the Programs and Scripts there needs to be some sort of use count implemented.
For example, an action could have an extra int (ie a counter) associated to it if the card is a spell, that counter could = 1, and if its a Program it could be an int above the number of possible viable moves (e.g. counter = 200). Then when a card's actions are executed, the int could be decreased. If after an action was checked that int decreases to 0, the action should be removed from the [Action], then when [Action] is the empty list, the card would be removed from play?
But then the health would need to be encoded somehow.
Maybe its just easier to define data Card = Program | Script | Error, where Error = Program | Script
Whatever's decided ill get around to implementing in the morning
There was some discussion in #9, we decided 3 constructors would be better, so there would be 1 constructor for each card with the fields listed in the table (plus any I missed)
Specific comment: https://github.com/fpclass/perpetual-haskelling-initiative/pull/9#issuecomment-627339879
Yeahp, i see that now. A much simpler solution!
I think we've done the data structures (although Instr
is still a work in progress), so now its time to move onto function implementations. There's now a Game.hs
module which contains some important functions - processMove
and setupGame
.
setupGame
takes the decks for player 1 and player 2 and generates the starting board and the starting player (1 or 2). This shouldn't be too bad as its mostly just filling in the defaults listed in the README
then some random stuff like picking the starting player and shuffling the decks (this function isn't currently done in the IO or Handler monad, but it might be good to be so we can use the monadic random functions)
processMove
takes a set of cards to play, the player who is playing those cards and the current board and attempts to complete the move. It has to sanity check the cards, making sure the player has enough points to play them etc (although checking they have the card and the move isn't empty is done by the server) and process the effects of the cards, so this is quite a big job - we can probably split it into smaller sections that different people can work on though.
I know @demonkittyRC was talking about doing some of this, anyone else want to help?
I'd be up for working with @demonkittyRC on this.
Though
setupGame
there's no point returning the starting player as well as the board because the current player is already stored in the board. (I'll make sure to change where setupGame
is used if I do make that change)Yeah there was a change to Board
so that's redundant now (I believe this change is in #19)
I thought the player could play multiple cards so long as its within their cost limit for that turn, if not that's easy enough to change. We should also change the README
if that's the case as that says cards not card.
Hey all,
Haven't had time to read all comments on this so far but I do have an understanding of hearthstone as well as a bit on battlegrounds and a few other card games, nothing too much but I play it a bit.
Anyways one interesting idea would be to implement PHP as a language (I know this may be considered heresy to some so hear me out), PHP would be the blue equivalent in mtg which is essentially debuffs, counterspells or any evasive effects hence it would be perfectly suited for such a broken language.
To the suggestion of combining programs on play this is close to the magnetic mechanic form hearthstone or the bestow for MTG where the difference being when bestow creature dies the minion becomes an independent living minion but in hearthstone it 'fully merges'. Both share effects or properties of minions.
There are potential for static counters which may be more prevalent maybe in java or perhaps for all languages/ classes which may match the c'thun or galakrond (this is one class instance) where independent cards in the set buff the single card (minions give +X/+X) wherever he is to c'thun and has size related battlecry, galakrond has an invoke ability that causes a different effect for each class and improves the card itself at intervals).
Also an interesting thing, do we have an idea for a Forbidden one Exodia win con?
We need to design the basic game mechanics and implement them, this probably includes: