Перейти к содержанию

Игра на тему программирования.


keng

Рекомендуемые сообщения

Наткнулись буквально сегодня с утра вместе с коллегами. Краткая суть - даны этажи, лифты и API (Application Programming Interface, набор функций, если коротко) для управления лифтами. Код - на javascript, но интуитивно-понятен, есть документация и примеры. Очень затягивает!

 

Вот [ссылка].

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

Наткнулись буквально сегодня с утра вместе с коллегами. Краткая суть - даны этажи, лифты и API (Application Programming Interface, набор функций, если коротко) для управления лифтами. Код - на javascript, но интуитивно-понятен, есть документация и примеры. Очень затягивает!

 

Вот [ссылка].

Вот зачем ты сказал об этой игре? Я же спать собирался... Завтра на учебу... Что ты со мной делаешь? :unsure:

Ссылка на комментарий
Поделиться на другие сайты

 Впервые я задумался, что очень жаль, что ни в этой игре и не в реальной жизни нельзя избирательно пропускать в лифт определенных пассажиров, а также нельзя определенных пассажиров принудительно (даже если они очень не хотят) высаживать на "этажах с ожиданием пока их не заберут", или высаживать в другие лифты. Если мы будем пропускать в лифт определенных пассажиров и выпускать даже там где они не хотели бы, то другие могли бы в бОльшем количестве доехать до места назначения.

 

В этой игре возможно идеальным решением будет взвешивание вариантов из всех возможных найденных за единицу времени. Но можно попробовать обобщить только некоторые варианты, чтобы это было достаточным решением

 

1) лифт должен немного подождать пока пассажиров наберется в нем, а не сразу ехать с одним человеком

2) лифт едет вверх или вниз, и по пути собирает и высаживает людей, но лифт не должен менять направление пока не отвезет всех пассажиров по текущему направлению до самого верхнего или до самого нижнего этажа

3) если лифт пустой, то он должен выбрать с какого этажа и в каком направлении начать движение, чтобы собрать как можно больше людей

4) когда лифтов много, то можно распределять для них задачи по маршрутам так, чтобы пункт 1, пункт 2, пункт 3 выполнялись наиболее выгодно с меньшим количеством лифтов

 

Вы слышали что-нибудь про инфузорию туфельку и движения ресничками по всему телу? Нигде не описывается как именно реснички выбирают направление, но я могу предположить, что окружающая среда (источники раздражения) и направляет эти реснички. По аналогии и с лифтами. Пассажиры это еда. Реснички это лифты. Если создать сесть из узлов оценивающих в единицу времени сумму весов случайных вариантов и запомненных вариантов, то можно запомнить новые варианты и эффективно перевозить пассажиров. Такая система вряд ли делается жесткими условиями "если А, то Б". Эти условия должны сами формироваться...

 

Короче ну нафиг, я пошел работать...  :-D

Ссылка на комментарий
Поделиться на другие сайты

MasterGH, это нормально, если я понял твое сообщение?) Утром глянул, подумал: "приду потом, поиграю может", ан нет) Теперь я вынужден думать о несовершенстве данной игры и о лифтах - в целом)
Ссылка на комментарий
Поделиться на другие сайты

Мы вчера сошлись на идее о глобальной очереди нажатых кнопок на этаже, лифты же в свободное время проверяют состояние этой очереди и исходя из своего текущего графика движения (направления и загруженности) и расстояния до этажа решали, будут ли останавливаться и забирать пассажира. Алгоритм работает довольно неплохо, но из-за особенностей JS иногда тупит. Вообще, игра - отличная демонстрация возможностей и принципов работы языка как такового.

Ссылка на комментарий
Поделиться на другие сайты

Алгоритм работает довольно неплохо, но из-за особенностей JS иногда тупит.

 

И сколько ты стадий прошел? Я на 7-ой застрял

MasterGH, это нормально, если я понял твое сообщение?) Утром глянул, подумал: "приду потом, поиграю может", ан нет) Теперь я вынужден думать о несовершенстве данной игры и о лифтах - в целом)

:-D

Ссылка на комментарий
Поделиться на другие сайты

Вот набросал перевод документации API
  


Пример первой стадии:
 

 


Elevator elevator (объект лифт)

elevator.goToFloor(3); // перейти на этаж после каких-то действий
elevator.goToFloor(2, true) // перейти на этаж сразу, сейчас, до каких-то действий
elevator.stop() // остановить лифт, очистить очередь. Редко используется для особых продвинутых исправлений
int elevator.currentFloor() // возвращает номер текущего этажа
float elevator.loadFactor() // возвращает float от 0.0 до 1.0 заполненности лифта. Если 1,0 то ехать не может
elevator.goingUpIndicator() // читает движение лифта
elevator.goingUpIndicator(bool) // устанавливает движение лифта (влияет на поведение пассажиров при остановке на этажах)
elevator.goingDownIndicator() // читает движение лифта
elevator.goingDownIndicator(bool) // устанавливает движение лифта (влияет на поведение пассажиров при остановке на этажах)
int[] elevator.destinationQueue // возвращает очередь-массив этажей, по которым собрался идти лифт, можно менять эту очередь.
elevator.checkDestinationQueue() // вызывать для обновления изменений в очереди elevator.destinationQueue

int[] elevator.getPressedFloors() // возвращает массив нажатых этажей в лифте

-----
Event событие для elevator

idle // Событие появляется когда лифт завершил свои задачи

floor_button_pressed // Пассажир нажал кнопку в лифте

passing_floor // Срабатывает перед прохождением этажа floorNum с указанием движения лифта direction "up" или "down"

stopped_at_floor // Срабатывает, когда лифт остановился на этаже floorNum

--------------------------

Floor (объект этаж)

floor.floorNum() // количество этажей

Event событие для этажа

up_button_pressed // кто-то из пассажиров нажал на этаже кнопку вызова лифта для движения на верхний этаж. Если пассажир не сможте зайти в лифт, то он нажмет её еще раз





down_button_pressed // кто-то из пассажиров нажал на этаже кнопку вызова лифта для движения на нижний этаж. Если пассажир не сможет зайти в литф, то он нажмет её еще раз
 
Наиболее удачный вариант (не мой)

 

Лучший вариант (не мой)

 

 

Еще один вариант, не помню чей


 
Ну, а у мой код я приводить не буду... Дошел я до 7го уровня и в лом дальше. Синтаксис надо учить, ломает.

{    init: function(elevators, floors) {        var elevator = elevators[0]; // Использовать первый лифт (на 1-ой стадии он один)        elevator.on("idle", function() {            // Лифт встал на этаже и ничего не делает            elevator.goToFloor(0); // добавить в очередь движение на этаж 0            elevator.goToFloor(1); // добавить в очередь движение на этаж 1        });    },    update: function(dt, elevators, floors) {        // Функция обновления где        // DT (deltaTime) - разница игровых секунд (прим. от MasterGH тип не знаю сами проверите), прошедших с предыдущего вызова update-функции    }}
elevator.destinationQueue = [];elevator.checkDestinationQueue();
if(elevator.getPressedFloors().length > 0) {// Может быть лифту отправиться на некоторый этаж?}
elevator.on("idle", function() { ... });
elevator.on("floor_button_pressed", function(floorNum) {// Нужно ли лифту отправлятся на этаж floorNum?})
elevator.on("passing_floor", function(floorNum, direction) { ... });
elevator.on("stopped_at_floor", function(floorNum) {// Нужно решить куда идти лифту дальше?})
if(floor.floorNum() > 3) { ... }
floor.on("up_button_pressed", function() {// Может быть послать лифт на этот этаж floor ?})
floor.on("down_button_pressed", function() {// Может быть послать лифт на этот этаж floor ?})
{    init: function(elevators, floors) {        var reorder = true; //reorder floor order to minimize moves. Keep on true         var minimalfilled = 0; //set to 0.6 for minimal move challenges         var backtozero = false; //make elevators go back to floor zero if idle or not.        var uppressed = []; //keep track of up button presses        var downpressed = []; //keep track of down button presses        // loop over floors        _.each(floors, function(floor) {            // if an up button is pressed, add it to the list of up presses            floor.on("up_button_pressed", function() {                uppressed.push(floor.level);            });            // if a down button is pressed, add it to the list of down presses            floor.on("down_button_pressed", function() {                downpressed.push(floor.level);            });         });        // loop over elevators        _.each(elevators, function(elevator) {            // if a button is pressed in the elevator, go to that floor (order can be changed when a floor is passed)            elevator.on("floor_button_pressed", function(floorNum) {                elevator.goToFloor(floorNum);            });            // if idle, determine the next floor to go to            elevator.on("idle", function() {                // compute the center floor - unused                //var middle = Math.floor(floors.length/2);                var floor;                // if a down button is pressed, go to the floor where a button is pressed                if (downpressed.length > 0) {                    floor = downpressed.pop();                    //inProcessDown.push(floor);                // if an up button is pressed, go to the floor where an up button is pressed                // this comes after the down presses, because up presses mostly occur at ground floor, where plenty of elevators pass anyway                } else if (uppressed.length > 0){                    floor = uppressed.pop();                    //inProcessUp.push(floor);                // if the variable is set to true, and no buttons are pressed, go to ground floor                } else if (backtozero){                    floor = 0;                // stay on the current floor                } else {                    floor = elevator.currentFloor();                }                // go to the floor chosen above                elevator.goToFloor(floor);            });            // when stopping on a floor            elevator.on("stopped_at_floor", function() {                // if the elevator is not sufficiently filled, stay on the current floor                // can be used for the minimal move challenges                if (elevator.loadFactor()<minimalfilled){                    elevator.goToFloor(elevator.currentFloor(),true);                }            });            // when passing a floor, rearrange the queue            elevator.on("passing_floor", function(floorNum, direction) {                var arr = elevator.destinationQueue;                var uppressedIndex=uppressed.indexOf(floorNum);                var downPressedIndex=downpressed.indexOf(floorNum);                // see if someone pressed a floor button, if you're not full and you're going in the right direction add the floor to the queue                if(elevator.loadFactor()<=0.5 && (((uppressedIndex > -1) && direction == "up") || ((downPressedIndex > -1) && direction == "down"))){                    if (uppressedIndex > -1)                        uppressed.splice(uppressedIndex,1);                    if (downPressedIndex > -1)                        downpressed.splice(downPressedIndex,1);                    arr.push(floorNum);                                }                            // remove potential duplicate values from the queue                               var i,                len=arr.length,                out=[],                obj={};                for (i=0;i<len;i++) {                    obj[arr[i]]=0;                }                for (i in obj) {                    out.push(i);                }                // duplicates removed                // reorder the queue so floors on the path are first in the queue                if(reorder){                    out=out.sort();                    var out2=[];                    var out3=[];                    if(direction == "up"){                        for(i in out){                            if(out[i]>=floorNum){                                out2.push(out[i]);                            } else {                                out3.push(out[i]);                            }                        }                    } else {                        out = out.reverse();                        for(i in out){                            if(out[i]<=floorNum){                                out2.push(out[i]);                            } else {                                out3.push(out[i]);                            }                        }                    }                    out = out2.concat(out3);                }                elevator.destinationQueue = out;                elevator.checkDestinationQueue();            });                                });    },    update: function(dt, elevators, floors) {    }}
{    init: function(elevators, floors) {        var rotator = 0;        _.each(floors, function(floor) {            floor.on("up_button_pressed down_button_pressed", function() {                var elevator = elevators[(rotator++) % elevators.length];                elevator.goToFloor(floor.level);            });         });        _.each(elevators, function(elevator) {            elevator.on("floor_button_pressed", function(floorNum) {                elevator.goToFloor(floorNum);            });            elevator.on("idle", function() {                elevator.goToFloor(0);            });        });    },    update: function(dt, elevators, floors) {    }}
Изменено пользователем MasterGH
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.