ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/kgsueme/lib/KGS/Game/Tree.pm
Revision: 1.9
Committed: Sun Jun 1 10:10:21 2003 UTC (23 years, 4 months ago) by pcg
Branch: MAIN
Changes since 1.8: +6 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 package KGS::Game::Tree;
2    
3     use KGS::Constants;
4    
5     # _should_ be unified, but the two types are slightly different
6     # (this really looks like a grown, as opposed to designed, protocol)
7 pcg 1.6 # despite the claim of "innovation" etc...
8 pcg 1.1 my %marker_type = (
9     triangle => MARK_TRIANGLE,
10     square => MARK_SQUARE,
11     circle => MARK_CIRCLE,
12     small_b => MARK_SMALL_B,
13     small_w => MARK_SMALL_W,
14     );
15    
16     # exclusion masks... the bit on the left excludes (removes) the ones on the right
17     my %exclude_type = (
18     &MARK_TRIANGLE => MARK_SQUARE | MARK_TRIANGLE | MARK_CIRCLE | MARK_LABEL,
19     &MARK_SQUARE => MARK_SQUARE | MARK_TRIANGLE | MARK_CIRCLE | MARK_LABEL,
20     &MARK_CIRCLE => MARK_SQUARE | MARK_TRIANGLE | MARK_CIRCLE | MARK_LABEL,
21     &MARK_LABEL => MARK_SQUARE | MARK_TRIANGLE | MARK_CIRCLE | MARK_LABEL,
22     &MARK_SMALL_B => MARK_SMALL_B | MARK_SMALL_W | MARK_B | MARK_W | MARK_MOVE,
23     &MARK_SMALL_W => MARK_SMALL_B | MARK_SMALL_W | MARK_B | MARK_W | MARK_MOVE,
24 pcg 1.3 &MARK_GRAY_B => MARK_B | MARK_W | MARK_MOVE | MARK_GRAY_B | MARK_GRAY_W,
25     &MARK_GRAY_W => MARK_B | MARK_W | MARK_MOVE | MARK_GRAY_B | MARK_GRAY_W,
26     &MARK_B => MARK_SMALL_B | MARK_SMALL_W | MARK_B | MARK_W | MARK_MOVE | MARK_GRAY_B | MARK_GRAY_W,
27     &MARK_W => MARK_SMALL_B | MARK_SMALL_W | MARK_B | MARK_W | MARK_MOVE | MARK_GRAY_B | MARK_GRAY_W,
28 pcg 1.1 );
29    
30     sub init_tree {
31     my ($self) = @_;
32     $self->{tree} = [ { id => 0 } ];
33     }
34    
35     sub update_tree {
36 pcg 1.9 my ($self, $timestamp, $tree) = @_;
37 pcg 1.1
38     my $node = $self->{curnode};
39    
40     for (@$tree) {
41     my ($type, @arg) = @$_;
42     if ($type eq "add_child") {
43     $node = $self->{tree}[$arg[0] + 1]
44 pcg 1.3 or die "FATAL: referencing nonexistent node $arg[0]+1!";
45 pcg 1.1
46     my $new = { parent => $node->{id}, id => scalar @{$self->{tree}} };
47    
48     push @{$self->{tree}}, $new;
49     push @{$node->{children}}, $new->{id};
50    
51     $node = $new;
52    
53     } elsif (my $bit = $marker_type{$type}) {
54 pcg 1.4 my $ref = $node->{"$arg[1],$arg[2]"} ||= [];
55 pcg 1.1
56 pcg 1.4 $ref->[0] &= ~$exclude_type{$bit};
57     $ref->[0] |= $bit if $arg[0] != 2;
58     $ref->[1] |= $exclude_type{$bit};
59 pcg 1.1
60     } elsif ($type eq "label") {
61 pcg 1.4 my $ref = $node->{"$arg[1],$arg[2]"} ||= [];
62 pcg 1.1
63 pcg 1.4 $ref->[0] &= ~$exclude_type{&MARK_LABEL};
64     undef $ref->[2];
65 pcg 1.1
66     if (length $arg[0]) {
67 pcg 1.4 $ref->[0] |= MARK_LABEL;
68     $ref->[1] |= $exclude_type{&MARK_LABEL};
69     $ref->[2] = $arg[0];
70 pcg 1.1 }
71    
72 pcg 1.3 } elsif ($type eq "move" or $type eq "addstone" or $type eq "gray") {
73 pcg 1.7 if ($arg[1] < 255) {
74     my $ref = $node->{"$arg[1],$arg[2]"} ||= [];
75 pcg 1.4
76 pcg 1.7 my $bit = $arg[0] == 0 ? $bit | ($type eq "gray" ? MARK_GRAY_B : MARK_B)
77     : $arg[0] == 1 ? $bit | ($type eq "gray" ? MARK_GRAY_W : MARK_W)
78     : 0;
79 pcg 1.3
80 pcg 1.7 $ref->[0] &= ~$exclude_type{$bit};
81     $ref->[0] |= $bit | ($type eq "move" ? MARK_MOVE : 0);
82     $ref->[1] |= $exclude_type{$bit};
83 pcg 1.1
84 pcg 1.7 $self->event_move (0) if $self->{loaded} & $type eq "move";
85     } else {
86     warn "PLEASE REPORT: pass coordiates but type is $type" if $type ne "move";#d#
87    
88     $node->{pass} = 1;
89    
90     $self->event_move (1) if $self->{loaded};
91     }
92 pcg 1.6
93 pcg 1.1 } elsif ($type eq "comment") {
94 pcg 1.3 $node->{comment} .= $arg[0];
95    
96     } elsif ($type eq "player") {
97     $node->{player}[$arg[0]] = $arg[1];
98 pcg 1.1
99 pcg 1.9 } elsif ($type eq "rank") {
100     $node->{rank}[$arg[0]] = $arg[1];
101    
102 pcg 1.8 } elsif ($type eq "set_timer") {
103 pcg 1.9 $node->{timer}[$arg[0]] = [$timestamp, $arg[1], $arg[2]];
104 pcg 1.3
105     } elsif ($type eq "more") {
106     $self->{more} = 1;
107     $self->msg(get_tree => channel => $self->{channel}, node => @{$self->{tree}} - 1);
108    
109     } elsif ($type eq "done") {
110     $self->{loaded} = 1;
111     # nop
112 pcg 1.2
113 pcg 1.1 } else {
114 pcg 1.9 $node->{$type} = $arg[0]; # rules, date etc..
115 pcg 1.1 }
116     }
117    
118     $self->{curnode} = $node;
119     }
120    
121     sub get_path {
122     my ($self) = @_;
123    
124     my @nodes;
125    
126     my $node = $self->{curnode};
127    
128     for(;;) {
129     push @nodes, $node;
130     last unless $node->{parent};
131     $node = $self->{tree}[$node->{parent}];
132     }
133    
134     [reverse @nodes];
135     }
136    
137     sub set_node {
138     my ($self, $node) = @_;
139    
140     $self->{curnode} = $self->{tree}[$node + 1]
141     or die "set_node to undefined tree node $node+1";
142     }
143    
144 pcg 1.6 sub event_move { }
145 pcg 1.5 sub event_update_tree { }
146    
147 pcg 1.1 1;
148