aboutsummaryrefslogtreecommitdiff
path: root/src/CMI.cpp
blob: dfca22d4dd1cfb8a765b54586194edb8afb6dbc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "CMI.hpp"

namespace CMI{
    void HalfMove::Promote(){
        HalfMove *broot=GetBranchRoot();
        if(broot!=nullptr){
            HalfMove *parent=broot->GetParent();
            if (parent != nullptr) {
                if (parent->GetMainline() != broot) {
                    HalfMove *pparent=parent->GetParent();
                    // First update parent of parent:
                    if (pparent != nullptr) {
                        if (pparent->GetMainline() == parent)
                            pparent->SetMainline(broot);
                        else { 
                            pparent->AddVariation(broot);
                            pparent->RemoveChild(parent);
                        }
                    }
                    // Now update parent:
                    parent->RemoveChild(broot);
                    broot->AddVariation(parent);
                }
            }
        }
    }

    void HalfMove::SetAsMainline(){
        HalfMove *broot = GetBranchRoot();
        HalfMove *lastRoot;
        // Just promote until we cannot anymore
        do {
            lastRoot = broot;
            broot->Promote();
            broot = GetBranchRoot();
        } while (broot != lastRoot);
    }

    HalfMove* HalfMove::GetBranchRoot(){
        HalfMove *m = this;
        HalfMove *p = GetParent();
        while (p != nullptr) {
            if (p->GetMainline() != m) {
                return (m);
            }
            m = p;
            p = m->GetParent();
        }
        return m;
    }

    void HalfMove::AddVariation(HalfMove* m){
        m->SetIsBlack(IsBlack());
        m->SetNumber(GetNumber());
        m->SetParent(this);
        auto vars=GetVariations();
        vars.push_back(m);
        SetVariations(vars);
    }

    bool HalfMove::RemoveVariation(HalfMove* m){
        std::vector<HalfMove*> vars;
        bool removed=false;
        for(HalfMove *v: GetVariations()){
            if(m!=v)
                vars.push_back(v);
            else
                removed=true; 
        }
        if(removed)
            SetVariations(vars);
        return removed;
    }

    bool HalfMove::RemoveChild(HalfMove* m){
        if(GetMainline()==m){
            SetMainline(nullptr);
            return true;
        }
        return RemoveVariation(m);
    }
}