Доверяйте напарнику, или продолжаем карточный скрипт


Сегодня рассмотрим еще одно окончание партии в дурака и усовершенствуем скрипт отображения игры.

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


Осталось три игрока – я, сверху и слева. Я и сверху - мы как бы напарники (это не игра пара на пару, но и в такой игре нередко создаются союзы, автоматически) и до этого играли против слева и справа (второго и четвертого). Остались трое и теперь ход третьего. Он сходил так – кнопка «вариант 1» - подкинул вальта крестового, четвертый побился и потом мне ничего не оставалось, как выкинуть восьмерки и третий проиграл.

А вот если бы он пошел по варианту 2 – то есть подкинул короля козырного, затем отбился от меня, дал двух тузов, снова отбился и вышел, выкинув королей – то победил бы. Для этого, правда надо было доверять мне.

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

Теперь код. Уже стало немного универсальнее по сравнению с прошлыми набросками, но это все еще черновик, не судите строго. В дальнейшем я избавлюсь и от повторений кода и разграничу саму анимацию от расчета; сейчас мне главное добиться более-менее нормального варианта

Верстка

<div id="scene">
    <div class="scene_col">
        <div id="hand2" class="hand">
            <div class="hand_pos" id="hand_2_pos_1"></div>
            <div class="hand_pos" id="hand_2_pos_2"></div>
            <div class="hand_pos" id="hand_2_pos_3"></div>
            <div class="hand_pos" id="hand_2_pos_4"></div>
            <div class="hand_pos" id="hand_2_pos_5"></div>
            <div class="hand_pos" id="hand_2_pos_6"></div>
            <div class="hand_pos" id="hand_2_pos_7"></div>
        </div>
    </div>
    <div class="scene_col">
        <div id="hand3" class="hand">
            <div class="hand_pos" id="hand_3_pos_1"></div>
            <div class="hand_pos" id="hand_3_pos_2"></div>
            <div class="hand_pos" id="hand_3_pos_3"></div>
            <div class="hand_pos" id="hand_3_pos_4"></div>
            <div class="hand_pos" id="hand_3_pos_5"></div>
            <div class="hand_pos" id="hand_3_pos_6"></div>
            <div class="hand_pos" id="hand_3_pos_7"></div>
        </div>
        <div id="table">
            <div id="deck">
                <img class="flash_pos" src="images/card_back.png" />
            </div>
            <div id="area">
                <div class="tab_pos" id="tab_pos_1"></div>
                <div class="tab_pos" id="tab_pos_3"></div>
                <div class="tab_pos" id="tab_pos_5"></div>
                <div class="tab_pos" id="tab_pos_7"></div>
                <div class="tab_pos" id="tab_pos_9"></div>
                <div class="tab_pos" id="tab_pos_11"></div>
                <div class="tab_pos" id="tab_pos_2"></div>
                <div class="tab_pos" id="tab_pos_4"></div>
                <div class="tab_pos" id="tab_pos_6"></div>
                <div class="tab_pos" id="tab_pos_8"></div>
                <div class="tab_pos" id="tab_pos_10"></div>
                <div class="tab_pos" id="tab_pos_12"></div>
            </div>
            <div id="flash" >
                <img class="flash_pos" src="images/card_back.png" />
            </div>
        </div>
        <div id="hand1" class="hand">
            <div class="hand_pos" id="hand_1_pos_1"></div>
            <div class="hand_pos" id="hand_1_pos_2"></div>
            <div class="hand_pos" id="hand_1_pos_3"></div>
            <div class="hand_pos" id="hand_1_pos_4"></div>
            <div class="hand_pos" id="hand_1_pos_5"></div>
            <div class="hand_pos" id="hand_1_pos_6"></div>
            <div class="hand_pos" id="hand_1_pos_7"></div>
        </div>
    </div>
    <div class="scene_col" >
        <div id="hand4" class="hand">
            <div class="hand_pos" id="hand_4_pos_1"></div>
            <div class="hand_pos" id="hand_4_pos_2"></div>
            <div class="hand_pos" id="hand_4_pos_3"></div>
            <div class="hand_pos" id="hand_4_pos_4"></div>
            <div class="hand_pos" id="hand_4_pos_5"></div>
            <div class="hand_pos" id="hand_4_pos_6"></div>
            <div class="hand_pos" id="hand_4_pos_7"></div>
        </div>
    </div>
</div>
<div id="start"></div>


<br>
<button id="str0">Стартовая</button>  
<button id="str1">Вариант 1</button> 
<button id="str2">Вариант 2</button>     
<button id="str3">Вариант 3</button> 
Стили
<style>
#scene{
    height: 600px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-image: url(images/fon_table_1.png);
}
.hand_pos{
    margin-left: -50px !important;
    width: 71px;
    height: 96px;
}
.hand{
    margin-left: 50px;
    text-align: center;
    display: flex;
}
#table{
    height: 300px;
    display: flex;
    justify-content: start;
    width: 650px;
    align-items: center;
    padding: 10px;
}
.deck_pos, .tab_pos{
    width: 71px;
    height: 96px;
}
.tab_pos{
    margin-top: -50px;
}
#area{
    display: flex;
    min-width: 440px;
    height: auto;
    flex-wrap: wrap;
    margin-left: 10px;
}
.hand img{
display: unset!important;
}
#deck, #flash{
    width: 71px;
    height: 96px;
    margin-left: 70px;
    display: inline-flex;
}
#deck > img,  #flash> img{
    margin-left: -70px;
}
.flash_pos{
    z-index: 9999;
}
</style>
Скрипт

<script>

const names = {
        "6d": "0.jpg",
        "7d": "1.jpg",
        "8d": "2.jpg",
        "9d": "3.jpg",
        "10d": "4.jpg",
        "Jd": "5.jpg",
        "Qd": "6.jpg",
        "Kd": "7.jpg",
        "Ad": "8.jpg",
        "6s": "9.jpg",
        "7s": "10.jpg",
        "8s": "11.jpg",
        "9s": "12.jpg",
        "10s": "13.jpg",
        "Js": "14.jpg",
        "Qs": "15.jpg",
        "Ks": "16.jpg",
        "As": "17.jpg",
        "6c": "18.jpg",
        "7c": "19.jpg",
        "8c": "20.jpg",
        "9c": "21.jpg",
        "10c": "22.jpg",
        "Jc": "23.jpg",
        "Qc": "24.jpg",
        "Kc": "25.jpg",
        "Ac": "26.jpg",
        "6h": "27.jpg",
        "7h": "28.jpg",
        "8h": "29.jpg",
        "9h": "30.jpg",
        "10h": "31.jpg",
        "Jh": "32.jpg",
        "Qh": "33.jpg",
        "Kh": "34.jpg",
        "Ah": "35.jpg"
    }

function build_pos_card(card){
    let src = convert_name_to_src(card);
    return `<img class="pos_card" id="card_${card}" src="${src}" />`;
}

let cards_table = 0;
let cards_hand1 = 0;
let cards_hand2 = 0;
let cards_hand3 = 0;
let cards_hand4 = 0;
let delay = 0;
full_reset();

//стартовая позиция 
let variant0 = Array("1+ 8d", "1+ 8c","3+ Ad", "3+ Kd", "3+ As", "3+ Ks", "3+ Kc","3+ Jc","3+ Jd","4+ Qd");

//варианты игры
let variant1 = Array("3-4 Jc", "4-t Qd", "f Jc", "f Qd", "1-3 8c", "3-t Kc", "1-3 8d", "3-t Jd");
let variant2 = Array("3-4 Kd", "4+ Kd", "1-3 8c", "3-t Jc", "f 8c", "f Jc", "3-4 As", "4-t Qd", "3-4 Ad"
,"4+ As","4+ Qd","4+ Ad", "1-3 8d", "1-3 8d", "3-t Jd", "f 8d", "f Jd", "3-4 Kc", "3-4 Ks");
let variant3 = Array("3-4 Kd", "4+ Kd", "1-3 8c", "3-t Jc", "1-3 8d", "3-t Jd", "f Jc", "f 8c",
 "f 8d", "f Jd", "3-4 As", "4-t Qd", "3-4 Ad" ,"4+ As","4+ Ad", "4+ Qd", "3-4 Kc", "3-4 Ks");
function full_reset(){
    cards_table = 0;
    cards_hand1 = 0;
    cards_hand2 = 0;
    cards_hand3 = 0;
    cards_hand4 = 0;

    jQuery(".pos_card").remove();

    Object.entries(names).forEach(([key, value]) => {
        let img = `<img class="pos_card" id="card_${key}" src="images/${value}" />`;
        jQuery("#deck").prepend(img);
    });
}

function stepAnimation(start, end){
    // Получаем элементы
    let box1 = document.getElementById(start);
    let box2 = document.getElementById(end);

    box1.setAttribute("style", "z-index: "+end.charAt(end.length - 1));

    // Получаем текущие позиции элементов
    let rect1 = box1.getBoundingClientRect();
    let rect2 = box2.getBoundingClientRect();

    // Вычисляем смещения
    let translateX = rect2.left - rect1.left;
    let translateY = rect2.top - rect1.top;

    anime({
        targets: '#'+start,
        translateX: translateX,
        translateY: translateY,
        duration: delay,
        easing: 'linear',
        complete: function() {
            $('#'+start).appendTo('#'+end);
            $('#'+start).css("transform", "unset");
        }
    });

    


}

function parse_hod(str){
    let start = "";
    let end = "";
    let action = "";
    let numb = 0;

    let arr = str.split("");
    if (arr[1] == "-" || arr[0] == "t"){
        action = "table";
        start = "card_"+str.split(" ")[1];
        end = "tab_pos_";
    }
    else if (arr[0] == "f"){
        action = "flash";
        start = "card_"+str.split(" ")[1];
        end = "flash";
    }
    else if (arr[1] == "+"){
        action = "hand";
        start = "card_"+str.split(" ")[1];
        end = `hand_${arr[0]}_pos_`;
        numb = arr[0];
    }

    let obj = {
        "action": action,
        "start": start,
        "end": end,
        "numb":  numb
    }
    return obj;
}

function job_variant(variant){
    arr_hod = variant;

arr_hod.forEach((hod, idx) => {
    obj = parse_hod(hod);

    if (obj['action'] == "table"){
        cards_table++;
        (function(obj, cards_table) {        
            setTimeout(() => {
                stepAnimation(obj['start'], obj['end']+cards_table);
            },  delay*idx);
        })(obj, cards_table);
    }
    if (obj['action'] == "hand"){
        if (obj['numb'] == 1){
            cards_hand1++;
            if (cards_table > 0){
                cards_table--;
            }            
            (function(obj, cards_hand1) {        
                setTimeout(() => {
                    stepAnimation(obj['start'], obj['end']+cards_hand1);
                },  delay*idx);
            })(obj, cards_hand1);
        }
        if (obj['numb'] == 2){
            cards_hand2++;
            if (cards_table > 0){
                cards_table--;
            }  
            (function(obj, cards_hand2) {        
                setTimeout(() => {
                    stepAnimation(obj['start'], obj['end']+cards_hand2);
                },  delay*idx);
            })(obj, cards_hand2);
        }
        if (obj['numb'] == 3){
            cards_hand3++;
            if (cards_table > 0){
                cards_table--;
            }  
            (function(obj, cards_hand3) {        
                setTimeout(() => {
                    stepAnimation(obj['start'], obj['end']+cards_hand3);
                },  delay*idx);
            })(obj, cards_hand3);
        }
        if (obj['numb'] == 4){
            cards_hand4++;
            if (cards_table > 0){
                cards_table--;
            }  
            (function(obj, cards_hand4) {        
                setTimeout(() => {
                    stepAnimation(obj['start'], obj['end']+cards_hand4);
                },  delay*idx);
            })(obj, cards_hand4);
        }
    }
    if (obj['action'] == "flash"){
        cards_table--;
        (function(obj, cards_table) {        
            setTimeout(() => {
                stepAnimation(obj['start'], obj['end']);
            },  delay*idx);
        })(obj, cards_table);
        
        
    }
});
}

job_variant(variant0);
jQuery("#str0").on('click', function() {
    delay = 0;
    full_reset();
    job_variant(variant0);
}); 


jQuery("#str1").on('click', function() {
    delay = 1000;
    job_variant(variant1);  
}); 

jQuery("#str2").on('click', function() {
    delay = 1000;
    job_variant(variant2);  
}); 

jQuery("#str3").on('click', function() {
    delay = 1000;
    job_variant(variant3);  
}); 


</script>
Как видите, я снова вернулся к более универсальному методу анимации, перенес изначально карты в колоду. Добавил бой и, самое главное, - сделал движение карт не только на стол, но и обратно.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, личное, карты, js, css




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Мизофония: определение, причины, способы борьбы
Гарантия на сайты
Урок 12. Перегрузка оператора преобразования C#