void measurement_step(struct measurement *trace, float dt)
{
    trace->accumulated_time += dt;

    if (trace->accumulated_time > trace->next_period)
    {
        // Generate new control point value
        float next = lerp(trace->min_intensity, trace->max_intensity, rng_next(), UINT16_MAX);

        // Weight heavily towards the previous point
        trace->points[trace->start] = (2 * trace->points[wrap(trace->start + 3)] + next) / 3;

        // Increment control point
        trace->start = wrap(trace->start + 1);

        trace->accumulated_time -= trace->next_period;
        trace->next_period = lerp(trace->min_period, trace->max_period, rng_next(), UINT16_MAX);
    }

    // Evaluate the catmull-rom spline
    float t = trace->accumulated_time / trace->next_period;
    float p0 = trace->points[wrap(trace->start + 0)];
    float p1 = trace->points[wrap(trace->start + 1)];
    float p2 = trace->points[wrap(trace->start + 2)];
    float p3 = trace->points[wrap(trace->start + 3)];

    trace->value = p1 + 0.5f*t*(p2 - p0 + t*((2*p0 - 5*p1 + 4*p2 - p3) + t*(3*p1 - 3*p2 + p3 - p0)));
}
// Initialize first four parameters
void measurement_init(struct measurement *trace, float range[2], float timescale[2])
{
    trace->min_period = timescale[0];
    trace->max_period = timescale[1];
    trace->min_intensity = range[0];
    trace->max_intensity = range[1];
    trace->value = lerp(range[0], range[1], rng_next(), UINT16_MAX);

    for (uint8_t i = 0; i < 4; i++)
        trace->points[i] = trace->value;
}
Example #3
0
File: rngc.c Project: kgie/berto
// -- OCaml wrapper function returning a random permutation of n integers
// -- in the range [0, n - 1].
CAMLprim value wrap_rng_perm(value vn)
{
  CAMLparam1(vn);
  CAMLlocal2(ar, h);

  int j, k;

  // -- The OCaml - C - interface requires to use Store_field() macros
  // -- for block access even for integers. This is probably quite
  // -- inefficient. Therefore a working arrays is defined here
  static int work[NWORK];

  // -- check constraints
  const int n = Int_val(vn);
  if (n < 0 || n >= NWORK) 
    caml_invalid_argument("Rng.perm: n out of bounds");

  // -- OCaml does not allow for heap allocated zero-sized arrays;
  // -- return atom instead
  if (n == 0)
    CAMLreturn(Atom(0));

  // -- initialize work array
  for (j = 0; j < n; j++)
    work[j] = j;

  // -- perform permutation by successively drawing numbers from the RNG
  // -- and swapping values
  for (j = n - 1; j > 0; j--) {
    k = rng_next() % (j + 1);       // -- positive int between 0 .. j
    h = work[k];
    work[k] = work[j];
    work[j] = h;
  }

  // -- allocate n-element array and initialize with work
  ar = caml_alloc(n, 0);
  for (j = 0; j < n; j++)
    Store_field(ar, j, Val_int(work[j]));

  CAMLreturn(ar);
}
Example #4
0
File: rngc.c Project: kgie/berto
// -- Ocaml wrapper function returning an array of n double prec
// -- random numbers in the open interval (0, 1).
CAMLprim value wrap_rng_get_array(value vn)
{
  CAMLparam1(vn);
  CAMLlocal1(ar);

  int j;

  // -- check constrains
  const int n = Int_val(vn);
  if ( n < 0 )
    caml_invalid_argument("Rng.get_array: n must be positive or 0");

  // -- OCaml does not allow for heap allocated zero-sized arrays;
  // -- return atom instead
  if (n == 0)
    CAMLreturn(Atom(0));

  // -- allocate block and initialize
  ar = caml_alloc(n * NDBL, Double_array_tag);
  for (j = 0; j < n; j++)
    Store_double_field(ar, j, fac * rng_next());

  CAMLreturn(ar);
}
Example #5
0
File: rngc.c Project: kgie/berto
// -- OCaml wrapper function returning an 31 or 63 bit integer in the
// -- closed interval [0, n - 1].
CAMLprim value wrap_rng_get_int(value n)
{
  CAMLparam1(n);
  CAMLreturn(Val_long( (rng_next() - 1) % Long_val(n) ));
}
Example #6
0
File: rngc.c Project: kgie/berto
// -- OCaml wrapper function returning a double value in the 
// -- open interval (0.0, 1.0).
CAMLprim value wrap_rng_get()
{
  CAMLparam0();
  CAMLreturn(caml_copy_double(fac * rng_next()));
}
Example #7
0
int
mahjong(unsigned seed)
{
    Taku taku;
    rng_init(seed);
    init_taku(&taku);
    taku.chicha = rng_next() % N_PLAYER;

    while (taku.kyoku < 8) {
        taku_wo_miseru(&taku);
        shipai(&taku);
        taku_wo_miseru(&taku);
        kaimen(&taku);
        taku_wo_miseru(&taku);
        haipai(&taku);
        taku_wo_miseru(&taku);
        taku.teban = oya(&taku);
        while (rest_tsumo(&taku.yama)) {
            unsigned pai;
            unsigned info;
            unsigned action;
            unsigned nakite;
            Kawa *kawa;
            pai = tsumo_from_yama(&taku.yama);
            taku.current = taku.yama.narabi + taku.yama.tsumo_idx;
after_tsumo:
            taku_wo_miseru(&taku);
            info = tsumo_select_action(&taku, pai);
            action = info_to_action(info);
            kawa = &taku.kawa[taku.teban];
            switch (action) {
            case ACTION_KAKAN:
                pai = info_to_pai(info);
                info = chankan_select_action_all(&taku, pai);
                nakite = info_to_player(info);
                if (taku.teban != nakite) {
                    taku.teban = nakite;
                    goto after_hohra;
                }
            case ACTION_ANKAN:
                pai = tsumo_from_rinshan(&taku.yama);
                goto after_tsumo;
            case ACTION_RIICHI:
                taku.tenbo[taku.teban] -= 1000;
                taku.riichibo++;
                kawa->riichi_idx = kawa->sute_idx;
            case ACTION_SUTE:
                pai = info_to_pai(info);
                taku.current = kawa->narabi + kawa->sute_idx;
                kawa->narabi[kawa->sute_idx++] = pai;
                goto after_sute;
            case ACTION_TSUMO:
                goto after_hohra;
            }
after_sute:
            taku_wo_miseru(&taku);
            if (is_sufurenda(&taku))
                goto after_ryukyoku;
            info = furo_select_action_all(&taku, pai);
            nakite = info_to_player(info);
            action = info_to_action(info);
            if (action == ACTION_SANCHAHOH)
                goto after_ryukyoku;
            if (taku.teban != nakite) {
                taku.teban = nakite;
                kawa = &taku.kawa[taku.teban];
                switch (action) {
                case ACTION_RON:
                    goto after_hohra;
                case ACTION_CHI:
                case ACTION_PON:
                case ACTION_MINKAN:
                    info = furo_sute_action(&taku, info);
                    pai = info_to_pai(info);
                    taku.current = kawa->narabi + kawa->sute_idx;
                    kawa->narabi[kawa->sute_idx++] = pai;
                    goto after_sute;
                case ACTION_THROUGH:
                    break;
                }
            }
            if (is_suchariichi(&taku))
                goto after_ryukyoku;
            if (is_sukaikan(&taku))
                goto after_ryukyoku;
            taku.teban = (taku.teban + 1) % N_PLAYER;
        }
after_ryukyoku:
        taku_wo_miseru(&taku);
        if (ryukyoku(&taku))
            taku.kyoku++;
        else
            taku.tsumibo++;
        continue;
after_hohra:
        taku_wo_miseru(&taku);
        if (hohra(&taku))
            taku.kyoku++;
        else
            taku.tsumibo++;
    }
    return 0;
}
Example #8
0
void
shuffle_narabi(uint8_t *narabi, unsigned n)
{
    while (--n)
        swap_narabi(narabi, n, rng_next()%n);
}