/vqdr/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/vqdr/trunk
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using VQDR.Expression;

public abstract class VQDR.Expression.AbstractPoolToken : FunctionToken {
  protected static Dice stadard_dice = new Dice.singel (10);

  protected AbstractPoolToken () {
    base ();
  }

  protected override void evaluate_self (Context instance) throws GLib.Error {
    int32 roll_res = 0;
    int32 pool_size = 0;
    int32 successes = 0;

    this.result_value.number = 0;

    StringBuilder strbldr = new StringBuilder ();
    strbldr.append (SYM_BEGIN);

    init_sequence (instance);

    pool_size = get_pool_size (instance);
    if (pool_size > MAX_TOKEN_ITERATIONS) {
        throw new Utils.ParamError.OUT_OF_BOUNDS
          (@"$(this.get_type ().name ()) Pool index: $(get_pool_size (instance))");
    }

    bool is_roll_again;
    int32 total_roll_number = 0;
    // XXX
    for (int32 i = 1; i <= pool_size; i++) {
      is_roll_again = false;
      do {
        if (strbldr.len < MAX_TOKEN_STRING_LENGTH) {
          if (is_roll_again) {
            strbldr.append (SYM_EXPLODE);
          } else if (i > 1) {
            strbldr.append (SYM_SEP);
          }
        }

        roll_res = get_roll (instance);

        successes = count_successes (instance, roll_res);

        if (strbldr.len < MAX_TOKEN_STRING_LENGTH) {
          strbldr.append (roll_res.to_string ());
        }

        /*
         * place a Success mark for every roll that successeeded.
         */
        for (var j = 0; j < successes; j++) {
          if (strbldr.len < MAX_TOKEN_STRING_LENGTH) {
            strbldr.append (SYM_SUCCESS);
          }
        }

        /*
         * place a Failure mark for every failed roll.
         */
        for (var j = 0; j > successes; j--) {
          if (strbldr.len < MAX_TOKEN_STRING_LENGTH) {
            strbldr.append (SYM_FAILURE);
          }
        }

        this.result_value.number += successes;
        
        total_roll_number++;
        if (total_roll_number > MAX_TOKEN_ITERATIONS) {
          throw new Utils.LoopError.TO_LONG 
            (@"$(get_function_name (this.get_type ())): Loop took more than $MAX_TOKEN_ITERATIONS to complete.");
        }
        is_roll_again = true;
      } while (roll_again (instance, roll_res, i));

      end_sequence (instance);
      if (get_max_pool_size (instance) < 1) {
        result_max_value.number = 1;
      } else {
        result_max_value.number = get_max_pool_size (instance);
      }

      if (strbldr.len < MAX_TOKEN_STRING_LENGTH) {
        strbldr.append (SYM_END);
        result_string = strbldr.str;
      } else {
        result_string = SYM_TRUNK_BEGIN + result_value.number.to_string () + SYM_TRUNK_END;
      }

    } // end for loop

  }

  /**
   * Tell if another roll is required.
   *
   * @param instance         the instance of the context to run in.
   * @param roll_result      the result to be evaluated.
   * @param pool_roll_number the number of rolls according to the pool size (zero base)
   *
   * @return ''true'' if another roll is required, ''false'' otherwise.
   */
  protected virtual bool roll_again (Context instance, int32 roll_result, int32 pool_roll_number) {
    return false;
  }

  /**
   * Used to initalize a specific values.
   */
  protected abstract void init_sequence (Context instance);

  /**
   * Return the pool size, or the number of rolls to performe.
   */
  protected abstract int32 get_pool_size (Context instance);

  /**
   * Returns the index of the parameter that contains the pool_size.
   */
  protected abstract int32 get_pool_index ();


  /**
   * Perform a roll and return the result.
   */
  protected abstract int32 get_roll (Context instance) throws GLib.Error;

  /**
   * Count the number of successes obtained with this roll.
   * (can be negative)
   *
   * @return the number of Successes for this roll.
   */
  protected abstract int32 count_successes (Context instance, int32 roll_result) throws GLib.Error;

  /**
   * Used to evetually performe controls after the pool rolls.
   */
  protected virtual void end_sequence (Context instance) throws GLib.Error {
    // NOOP
  }

  /**
   * Returns the maximum size of the pool.
   *
   * This should be equal to ''get_pool_size ()'', but the implementation is
   * allowed to specify any pool size.
   *
   * @return the maximum pool size.
   */
  protected virtual int64 get_max_pool_size (Context instance) throws GLib.Error {
    return get_pool_size (instance);
  }

}