← All posts tagged code

Kim

Вот @alv в #2677608 заявляет, что мол aisleriot карты не тасует. Давайте пойдём в исходники (исходник взят из https://github.com/GNOME/aisleriot.git) и проверим. В aisleriot/games/freecell.scm прямо сказано

(define (new-game)
  (initialize-playing-area)
  (set-ace-low)
  (make-standard-deck)
  (shuffle-deck)
...
  (deal-initial-setup)
...)

Вот оно создаёт калоду, тасует её и 

(define (deal-initial-setup)
  (let ((fields (list field-1 field-2 field-3 field-4
                               field-5 field-6 field-7 field-8))
        (half-fields (list field-1 field-2 field-3 field-4)))
    (deal-cards-face-up-from-deck DECK
                                  (append fields fields fields
                                          fields fields fields
                                          half-fields))))

раздаёт по очереди шесть раз на восемь полей, а потом ещё один раз на первые четыре.

Может тусует криво? Смотрим в aisleriot/games/api.scm:

(define-public (shuffle-deck)
  (let* ((vec (list->vector DECK))
         (len (vector-length vec)))
    (set! DECK (shuffle-deck-helper vec '() 0 len))))
(define-public (shuffle-deck-helper deck result ref1 len)
  (if (zero? len)
      result
      (let* ((ref2 (+ ref1 (aisleriot-random len)))
             (val-at-ref2 (vector-ref deck ref2)))
        (vector-set! deck ref2 (vector-ref deck ref1))
        (shuffle-deck-helper deck (cons val-at-ref2 result) (+ ref1 1) (- len 1)))))

Что тут происходит? Мы рендомно выбираем элемент из списка начиная с (количество уже выбранных) до (количество карт в колоде). Запоминаем выбранный элемент, а на его место в колоду кладём элемент с минимальным не выбранным номером. Например при выборе самой первой карты aisleriot-random вернул нам номер 27, тогда мы берём 27 карту, откладываем её в отдельную стопку, а на её место кладём первую карту. В следующий раз мы выбираем из разложенных карт начиная со _второй_. 

Ну может всё таки брешут схемокодеры и косяк в aisleriot-random? Проверяем метод в aisleriot/games/card-monkey.scm:

(define-public (aisleriot-random n)
    (random n))

Действительно, тут сложно возражать. Так что либо в версии guile у @alv random совсем не random, либо что-то брешит этот ваш @alv. На всякий случай проверим и исходник guile (исходник получен по apt-get source guile-2.0). Не углубляясь в реализацию можем увидеть следующее guile-2.0-2.0.9+1/libguile/random.c:

/*
 * The prepackaged RNG
 *
 * This is the MWC (Multiply With Carry) random number generator
 * described by George Marsaglia at the Department of Statistics and
 * Supercomputer Computations Research Institute, The Florida State
 * University (http://stat.fsu.edu/~geo).
 *
 * It uses 64 bits, has a period of 4578426017172946943 (4.6e18), and
 * passes all tests in the DIEHARD test suite
 * (http://stat.fsu.edu/~geo/diehard.html)
 */

Так вот, период 4578426017172946943 немного больше, чем 12, так что брешит этот ваш @alv.

Kim

В общем не осилил перевести эту железяку в low power run mode. Фигачу такой код:

#include <libopencm3/stm32/rcc.h> 
#include <libopencm3/stm32/pwr.h> 
#include <libopencm3/stm32/flash.h> 

int main()
{
  clock_scale_t myclock_config = {
    .hpre = RCC_CFGR_HPRE_SYSCLK_DIV2,
    .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV,
    .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV,
    .voltage_scale = RANGE2, // Документация требует Range2 для low power run mode
    .flash_config = FLASH_ACR_LATENCY_0WS,
    .apb1_frequency = 65536,
    .apb2_frequency = 65536,
    .msi_range = RCC_ICSCR_MSIRANGE_65KHZ, // Для работы требуется MSIRANGE не больше первого. Ставим нулевой.
  };
  rcc_clock_setup_msi(&myclock_config);
  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_PWREN);
  PWR_CR |= PWR_CR_LPSDSR;
  PWR_CR |= PWR_CR_LPRUN;
  while(1) {
      __asm__("nop");
    }
}

А в результате, хоть делай "PWR_CR |= PWR_CR_LPRUN;" хоть не делай -- жрёт оно под 1 милиампер, вместо ожидаемых 40 микроампер.