It is currently 26 Apr 2024, 18:45
   
Text Size

Testing

Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins

Testing

Postby mtgrares » 27 Mar 2009, 18:20

I posted this as a comment on my blog about testing.

Testing is a hard but interesting subject. Hard because MTG Forge's architecture doesn't support testing but we all know that testing is important.

The truth is that this is a free project that is done in our spare time and while it doesn't always work 100% it is still very impressive. Although I'm glad willow and his Wagic project supports testing and has a great many cards.
The truth is that I'm sort of a perfectionist and could go crazy testing everything forwards and backwards, but MTG Forge works and it has a large number of cards and that is the only thing I care about.
mtgrares
DEVELOPER
 
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times

Re: Testing

Postby DennisBergkamp » 27 Mar 2009, 18:45

Willow is onto something though, testing hundreds of cards in a matter of minutes sounds great to me :)

But, how to implement regression tests into MTGForge? I have no clue.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Testing

Postby mtgrares » 27 Mar 2009, 18:49

But, how to implement regression tests into MTGForge? I have no clue.
The only way is to design the program with testing in mind from the ground up. Since I haven't done much with version 2.0, I guess I need to make sure it supports regression testing like JUnit.
mtgrares
DEVELOPER
 
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times

Re: Testing

Postby frwololo » 28 Mar 2009, 09:01

mtgrares wrote:
But, how to implement regression tests into MTGForge? I have no clue.
The only way is to design the program with testing in mind from the ground up. Since I haven't done much with version 2.0, I guess I need to make sure it supports regression testing like JUnit.
I disagree, it can work even with a bad initial design.
I've had a look at the MTGForge source, and I'd like to re-formulate what I said on your blog, with my new knowledge of your code:
I haven't done any Java in a long time so I'll go with pseudo-code in my explanations, sorry for that.
The basics in Wagic is that the TestPlayer inherits from the AIPlayer (which itself inherits from the Player class).
In Forge unfortunately, ComputerAI_General.java contains stuff for the AI, but also actions for the game engine. for example, in declare_attackers(), a line such as:
Code: Select all
 att[i].tap();
This line should not be in the AI code but somehow in the engine code. The proof is that you have the same method call on the human side, in Input_Attack.java (in method select_card).
So theoretically, the attacking rules could be different between the AI and a human player, which does not really make sense from a design point of view.

I'm not here to give lessons, my own project has thousands of small design glitches like this one, this is just an example to state my point:
if you wanted to add a TestPlayer the way I did it for Wagic, half of the code would need to be rewritten, which is not cool.

So now I'm suggesting an other way:
1) Allow Human VS Human Game
2) create a class (that will replace the human players during tests) that monitors the game(what phase is it ? is the stack empty ? Is it my turn to play ?) and makes calls to inputControl.selectCard and other public methods of inputControl. Or if you want upper level, this class could send crafted mouseEvents to the interface.

The rest depends on how you want to implement it, but it's basically an extra radio button in the initial interface that says "test", then in that case human players are replaced by this new class that will read its input from a text file somewhere and call inputControl's methods or send mouseEvents to GuiDisplay2.

I hope I'm making sense, I spent a few hours looking at Forge's code (actually, more 1h30 installing a Java IDE, and 30 minutes looking at the actual code), but I probably won't have the time or the motivation to actually do it for you.
frwololo
DEVELOPER
 
Posts: 265
Joined: 21 Jun 2008, 04:33
Has thanked: 0 time
Been thanked: 3 times

Re: Testing

Postby DennisBergkamp » 28 Mar 2009, 17:28

Frwolo,

Thanks for your input. It does sound like a bit longer than an afternoon coding, that's for sure ;)
But, I will definitely think about this and consider how to implement something like Human vs Human (or Computer vs Computer?), and discuss the details with rares or Rob Cashwalker.
As of now, I'm not really familiar enough with some of the lower level code to even know where to start :)

By the way, I just noticed there's some kind of test thing already implemented into MTGForge, in the file "RunTest.java". It looks like these are basically hard-coded tests and seem pretty limited, and unfortunately, when I try to run this, the thing hangs on the combat code tests already (I think due to the same bug related to Raging Goblin not being able to attack on turn 1).
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Testing

Postby Rob Cashwalker » 29 Mar 2009, 05:51

Human vs human.... As a solitare-style, like you could play both sides of the table.... That just might be possible.

Phase.java:
Code: Select all
  private String phases[][] =
  {
    //human's turn
    {Constant.Player.Human    , Constant.Phase.Untap}                                  ,
//   {Constant.Player.Human    , Constant.Phase.Upkeep}                                  ,
    {Constant.Player.Human    , Constant.Phase.Draw}                                     ,
    {Constant.Player.Human    , Constant.Phase.Main1}                                  ,
    {Constant.Player.Human    , Constant.Phase.Combat_Declare_Attackers}               ,
    {Constant.Player.Computer , Constant.Phase.Combat_Declare_Blockers}                ,
    {Constant.Player.Human    , Constant.Phase.Combat_Declare_Blockers_InstantAbility} ,
    {Constant.Player.Computer , Constant.Phase.Combat_Declare_Blockers_InstantAbility} ,
    {Constant.Player.Human    , Constant.Phase.Combat_FirstStrikeDamage}               , //TODO: need to allow computer to have priority (play instants and abilities).
    {Constant.Player.Human    , Constant.Phase.Combat_Damage}                          ,
    {Constant.Player.Human    , Constant.Phase.Main2}                                  ,
    {Constant.Player.Human    , Constant.Phase.At_End_Of_Turn}                         ,
//   {Constant.Player.Computer , Constant.Phase.End_Of_Turn}                            ,
    {Constant.Player.Human    , Constant.Phase.Until_End_Of_Turn}                      ,
    {Constant.Player.Human    , Constant.Phase.Cleanup}                                  ,

    //computer's turn
    {Constant.Player.Computer    , Constant.Phase.Untap}                                  ,
    {Constant.Player.Computer    , Constant.Phase.Draw}                                     ,
    {Constant.Player.Computer , Constant.Phase.Main1}                                  ,
    {Constant.Player.Computer , Constant.Phase.Combat_Declare_Attackers}               ,
    {Constant.Player.Human    , Constant.Phase.Combat_Declare_Blockers}                ,
    {Constant.Player.Computer , Constant.Phase.Combat_Declare_Blockers_InstantAbility} ,
    {Constant.Player.Human    , Constant.Phase.Combat_Declare_Blockers_InstantAbility} ,
    {Constant.Player.Human    , Constant.Phase.Combat_FirstStrikeDamage}               ,  //TODO: need to allow computer to have priority (play instants and abilities).
    {Constant.Player.Human    , Constant.Phase.Combat_Damage}                          ,
    {Constant.Player.Computer , Constant.Phase.Main2}                                  ,
    {Constant.Player.Computer , Constant.Phase.At_End_Of_Turn}                         ,
    {Constant.Player.Human    , Constant.Phase.End_Of_Turn}                            ,
    {Constant.Player.Computer , Constant.Phase.Until_End_Of_Turn}                      ,
    {Constant.Player.Computer    , Constant.Phase.Cleanup}                                  ,
  };
Looks like all it would take is modifying the system to use something more generic like "Constant.Player.Player1" and "Constant.Player.Player2" and make the correct association with human and computer players. This would be the key to a computer vs computer mode as well.

I'm also thinking that there should be a way to set up a single turn structure that both players follow, instead of 2 turns per loop. Maybe I'm thinking too much, but if we did that too, then it might be possible to devise a scheme for a multi-player game....
The Force will be with you, Always.
User avatar
Rob Cashwalker
Programmer
 
Posts: 2167
Joined: 09 Sep 2008, 15:09
Location: New York
Has thanked: 5 times
Been thanked: 40 times

Re: Testing

Postby mtgrares » 06 Apr 2009, 20:36

I've been thinking about MTG Forge and testing. I initially said that MTG Forge couldn't support testing but it can. The two major parts of MTG Forge is the card's resolve code and combat, both which could support automated testing. (I'm not sure how to automate the code that lets the user select a legal target.)

Everything in MTG Forge can be setup "manually" in the code, like attacking and blocking creatures. Maybe I should write a few combat tests since combat is complicated with the interactions between wither, first strike, lifelink, etc...
mtgrares
DEVELOPER
 
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times


Return to Forge

Who is online

Users browsing this forum: No registered users and 173 guests


Who is online

In total there are 173 users online :: 0 registered, 0 hidden and 173 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 173 guests

Login Form