efgfunc.cc
来自「Gambit 是一个游戏库理论软件」· CC 代码 · 共 1,499 行 · 第 1/3 页
CC
1,499 行
//// $Source: /home/gambit/CVS/gambit/sources/gcl/efgfunc.cc,v $// $Date: 2002/08/27 18:57:16 $// $Revision: 1.5 $//// DESCRIPTION:// Implementation of extensive form editing functions//// This file is part of Gambit// Copyright (c) 2002, The Gambit Project//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//#include "base/base.h"#include "gsm.h"#include "portion.h"#include "gsmfunc.h"#include "base/gstatus.h"#include "game/efg.h"#include "game/efgutils.h"#include "game/efbasis.h"#include "game/sfg.h"//// Implementations of these are provided as necessary in gsmutils.cc//template <class T> Portion *ArrayToList(const gArray<T> &);// these added to get around g++ 2.7.2 not properly completing type// unification when gVector passed to the parameter...extern Portion *ArrayToList(const gArray<double> &);extern Portion *ArrayToList(const gArray<gRational> &);template <class T> Portion *ArrayToList(const gList<T> &);template <class T> Portion *gDPVectorToList(const gDPVector<T> &);//------------// ActionNumber//------------static Portion *GSM_ActionNumber(GSM &, Portion **param){ Action *a = ((ActionPortion *) param[0])->Value(); EFSupport *support = ((EfSupportPortion *) param[1])->Value(); return new NumberPortion(support->Find(a));}static Portion *GSM_BasisActionNumber(GSM &, Portion **param){ Action *a = ((ActionPortion *) param[0])->Value(); EFBasis *basis = ((EfBasisPortion *) param[1])->Value(); return new NumberPortion(basis->EFSupport::Find(a));}//-------------// Actions//-------------static Portion *GSM_Actions(GSM &, Portion **param){ if (param[0]->Spec().Type == porNULL) return new ListPortion; Infoset *infoset = ((InfosetPortion *) param[0])->Value(); EFSupport *support = ((EfSupportPortion *) param[1])->Value(); return ArrayToList(support->Actions(infoset));}static Portion *GSM_BasisActions(GSM &, Portion **param){ if( param[0]->Spec().Type == porNULL ) return new ListPortion; Infoset *s = ((InfosetPortion *) param[0])->Value(); EFBasis* sup = ((EfBasisPortion*) param[1])->Value(); Portion *por = (s->IsChanceInfoset()) ? ArrayToList(s->Actions()) : ArrayToList(sup->Actions(s->GetPlayer()->GetNumber(), s->GetNumber())); return por;}//--------------// AddAction//--------------static Portion *GSM_AddAction(GSM &, Portion **param){ EFSupport *support = ((EfSupportPortion *) param[0])->Value(); Action *action = ((ActionPortion *) param[1])->Value(); EFSupport *S = new EFSupport(*support); S->AddAction(action); return new EfSupportPortion(S);}static Portion *GSM_AddBasisAction(GSM &, Portion **param){ EFBasis *basis = ((EfBasisPortion *) param[0])->Value(); Action *action = ((ActionPortion *) param[1])->Value(); EFBasis *S = new EFBasis(*basis); S->AddAction(action); return new EfBasisPortion(S);}//-------------// Nodes//-------------static Portion *GSM_BasisNodeNumber(GSM &, Portion **param){ Node *n = ((NodePortion *) param[0])->Value(); EFBasis *basis = ((EfBasisPortion *) param[1])->Value(); return new NumberPortion(basis->Find(n));}static Portion *GSM_BasisNodes(GSM &, Portion **param){ if( param[0]->Spec().Type == porNULL ) return new ListPortion; Infoset *s = ((InfosetPortion *) param[0])->Value(); EFBasis* sup = ((EfBasisPortion*) param[1])->Value(); Portion *por = (s->IsChanceInfoset()) ? ArrayToList(s->Members()) : ArrayToList(sup->Nodes(s->GetPlayer()->GetNumber(), s->GetNumber())); return por;}static Portion *GSM_AddBasisNode(GSM &, Portion **param){ EFBasis *basis = ((EfBasisPortion *) param[0])->Value(); Node *node = ((NodePortion *) param[1])->Value(); EFBasis *S = new EFBasis(*basis); S->AddNode(node); return new EfBasisPortion(S);}//------------------// AddMove//------------------static Portion *GSM_AddMove(GSM &gsm, Portion **param){ Infoset *s = ((InfosetPortion *) param[0])->Value(); Node *n = ((NodePortion *) param[1])->Value(); n->Game()->AppendNode(n, s); gsm.UnAssignGameElement(n->Game(), true, porBEHAV | porEFSUPPORT); return new NodePortion(n->GetChild(1));}//--------------// Chance//--------------static Portion *GSM_Chance(GSM &, Portion **param){ efgGame &E = *((EfgPortion*) param[0])->Value(); return new EfPlayerPortion(E.GetChance());}//----------------// ChanceProb//----------------static Portion *GSM_ChanceProb(GSM &, Portion **param){ const Action *action = ((ActionPortion *) param[0])->Value(); Infoset *infoset = action->BelongsTo(); if (!infoset->GetPlayer()->IsChance()) throw gclRuntimeError("Action must belong to the chance player"); efgGame *efg = infoset->Game(); return new NumberPortion(efg->GetChanceProb(infoset, action->GetNumber()));}//---------------// Children//---------------static Portion *GSM_Children(GSM &, Portion **param){ const Node *n = ((NodePortion *) param[0])->Value(); efgGame *e = ((efgGame*) param[0]->Game()); return ArrayToList(e->Children(n));}//------------// Comment//------------static Portion *GSM_Comment(GSM &, Portion **param){ efgGame *efg = ((EfgPortion *) param[0])->Value(); return new TextPortion(efg->GetComment());}//---------------// CompressEfg//---------------static Portion *GSM_CompressEfg(GSM &, Portion **param){ EFSupport *S = ((EfSupportPortion *) param[0])->Value(); return new EfgPortion(CompressEfg((efgGame &) S->GetGame(), *S));}//---------------// CopyTree//---------------static Portion *GSM_CopyTree(GSM &gsm, Portion **param){ Node *n1 = ((NodePortion *) param[0])->Value(); Node *n2 = ((NodePortion *) param[1])->Value(); gsm.UnAssignGameElement(n1->Game(), true, porBEHAV | porEFSUPPORT); return new NodePortion(n1->Game()->CopyTree(n1, n2));}//-----------------// DeleteAction//-----------------static Portion *GSM_DeleteAction(GSM &gsm, Portion **param){ const Action *action = ((ActionPortion *) param[0])->Value(); Infoset *infoset = action->BelongsTo(); if (infoset->NumActions() == 1) throw gclRuntimeError("Cannot delete the only action at an infoset."); infoset->Game()->DeleteAction(infoset, action); gsm.UnAssignGameElement(infoset->Game(), true, porBEHAV | porEFSUPPORT); gsm.UnAssignEfgElement(infoset->Game(), porACTION, (Action *)action); return new InfosetPortion(infoset);}//----------------------// DeleteEmptyInfoset//----------------------static Portion *GSM_DeleteEmptyInfoset(GSM &gsm, Portion **param){ Infoset *infoset = ((InfosetPortion *) param[0])->Value(); gsm.UnAssignGameElement(infoset->Game(), true, porBEHAV | porEFSUPPORT); gsm.UnAssignEfgElement(infoset->Game(), porINFOSET, infoset); return new BoolPortion(infoset->Game()->DeleteEmptyInfoset(infoset));}//----------------// DeleteMove//----------------static Portion *GSM_DeleteMove(GSM &gsm, Portion **param){ Node *n = ((NodePortion *) param[0])->Value(); efgGame *e = ((efgGame*) param[0]->Game()); Node *keep = ((NodePortion *) param[1])->Value(); if (keep->GetParent() != n) throw gclRuntimeError("keep is not a child of node"); gsm.UnAssignGameElement(n->Game(), true, porBEHAV | porEFSUPPORT); for (int i = 1; i <= e->NumChildren(n); i++) if (n->GetChild(i) != keep) gsm.UnAssignEfgSubTree(n->Game(), n->GetChild(i)); gsm.UnAssignEfgElement(n->Game(), porNODE, n); return new NodePortion(n->Game()->DeleteNode(n, keep));}//-----------------// DeleteOutcome//-----------------static Portion *GSM_DeleteOutcome(GSM &gsm, Portion **param){ efgOutcome *outcome = ((EfOutcomePortion *) param[0])->Value(); efgGame *efg = outcome->GetGame(); gList<Node *> nodes; Nodes(*efg, nodes); for (int i = 1; i <= nodes.Length(); ) { if (efg->GetOutcome(nodes[i]) != outcome) { nodes.Remove(i); } else { i++; } } gsm.InvalidateGameProfile(outcome->GetGame(), true); gsm.UnAssignEfgOutcome(outcome->GetGame(), outcome); efg->DeleteOutcome(outcome); return ArrayToList(nodes);}//----------------// DeleteTree//----------------static Portion *GSM_DeleteTree(GSM &gsm, Portion **param){ Node *n = ((NodePortion *) param[0])->Value(); gsm.UnAssignGameElement(n->Game(), true, porBEHAV | porEFSUPPORT); gsm.UnAssignEfgSubTree(n->Game(), n); n->Game()->DeleteTree(n); return new NodePortion(n);}//--------------// IsDominated//--------------static Portion *GSM_IsDominated_Efg(GSM &, Portion **param){ Action *act = ((ActionPortion *) param[0])->Value(); EFSupport *S = ((EfSupportPortion *) param[1])->Value(); bool strong = ((BoolPortion *) param[2])->Value(); bool conditional = ((BoolPortion *) param[3])->Value(); gWatch watch; bool ret; ret = S->IsDominated(act, strong, conditional); ((NumberPortion *) param[4])->SetValue(watch.Elapsed()); return new BoolPortion(ret);}//----------// Game//----------Portion* GSM_Game_EfgElements(GSM &, Portion** param){ if (param[0]->Game()) return new EfgPortion((efgGame*) param[0]->Game()); else return 0;}//-------------// Infoset//-------------static Portion *GSM_Infoset_Node(GSM &, Portion **param){ if( param[0]->Spec().Type == porNULL ) return new NullPortion( porINFOSET ); Node *n = ((NodePortion *) param[0])->Value(); if (!n->GetInfoset()) return new NullPortion(porINFOSET); return new InfosetPortion(n->GetInfoset());}static Portion *GSM_Infoset_Action(GSM &, Portion **param){ if( param[0]->Spec().Type == porNULL ) { return new NullPortion( porINFOSET ); } const Action *a = ((ActionPortion *) param[0])->Value(); if (!a->BelongsTo()) return new NullPortion(porINFOSET); return new InfosetPortion(a->BelongsTo());}//-------------// Infosets//-------------static Portion *GSM_Infosets(GSM &, Portion **param){ EFPlayer *p = ((EfPlayerPortion *) param[0])->Value(); return ArrayToList(p->Infosets());}//----------------// InsertAction//----------------static Portion *GSM_InsertAction(GSM &gsm, Portion **param){ Infoset *s = ((InfosetPortion *) param[0])->Value(); gsm.UnAssignGameElement(s->Game(), true, porBEHAV | porEFSUPPORT); return new ActionPortion((Action *)s->Game()->InsertAction(s));}static Portion *GSM_InsertActionAt(GSM &gsm, Portion **param){ Infoset *s = ((InfosetPortion *) param[0])->Value(); const Action *a = ((ActionPortion *) param[1])->Value(); gsm.UnAssignGameElement(s->Game(), true, porBEHAV | porEFSUPPORT); return new ActionPortion((Action *)s->Game()->InsertAction(s, a));}//--------------// InsertMove//--------------static Portion *GSM_InsertMove(GSM &gsm, Portion **param){ Infoset *s = ((InfosetPortion *) param[0])->Value(); Node *n = ((NodePortion *) param[1])->Value(); n->Game()->InsertNode(n, s); gsm.UnAssignGameElement(s->Game(), true, porBEHAV | porEFSUPPORT); return new NodePortion(n->GetParent());}//---------------// IsConstSum//---------------static Portion *GSM_IsConstSum(GSM &, Portion **param){ efgGame &E = *((EfgPortion*) param[0])->Value(); return new BoolPortion(E.IsConstSum());}//---------------// IsConsistent//---------------static Portion *GSM_IsBasisConsistent(GSM &, Portion **param){ EFBasis *basis = ((EfBasisPortion *) param[0])->Value(); return new BoolPortion(basis->IsConsistent());}//----------------// IsPredecessor//----------------static Portion *GSM_IsPredecessor(GSM &, Portion **param){ Node *n1 = ((NodePortion *) param[0])->Value(); Node *n2 = ((NodePortion *) param[1])->Value(); return new BoolPortion(n1->Game()->IsPredecessor(n1, n2));}//---------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?