找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: a66

[分享] 小游戏、小工具-htm

  [复制链接]
发表于 6 天前 | 显示全部楼层
中小学古诗文学习工具,
怎么自己添加诗词

点评

a66
参考源码后添加:  详情 回复 发表于 6 天前
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享, 来看看有哪些小游戏
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
谢谢辛苦分享
回复

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
ohte 发表于 2026-3-21 09:07
中小学古诗文学习工具,
怎么自己添加诗词

参考源码后添加:

  1.     // ---------- 只保留一年级上册(2026最新教材)----------
  2.     const poemsByGrade = [
  3.         { grade: "一年级(上)", list: [
  4.             { title: "咏鹅", author: "骆宾王", dynasty: "唐", lines: ["鹅,鹅,鹅,", "曲项向天歌。", "白毛浮绿水,", "红掌拨清波。"], translation: "鹅呀鹅,弯着脖子向天唱歌。白色的羽毛浮在绿水,红掌拨动清澈的水波。" },
  5.             { title: "江南", author: "汉乐府", dynasty: "汉", lines: ["江南可采莲,", "莲叶何田田。", "鱼戏莲叶间。", "鱼戏莲叶东,", "鱼戏莲叶西,", "鱼戏莲叶南,", "鱼戏莲叶北。"], translation: "江南可以采莲,莲叶多么茂盛。鱼儿在莲叶间嬉戏。鱼在莲叶东边游,鱼在莲叶西边游,鱼在莲叶南边游,鱼在莲叶北边游。" },
  6.             { title: "悯农·其二", author: "李绅", dynasty: "唐", lines: ["锄禾日当午,", "汗滴禾下土。", "谁知盘中餐,", "粒粒皆辛苦。"], translation: "中午锄草,汗水滴进泥土。谁知道盘中的饭食,每一粒都那么辛苦。" },
  7.             { title: "古朗月行(节选)", author: "李白", dynasty: "唐", lines: ["小时不识月,", "呼作白玉盘。", "又疑瑶台镜,", "飞在青云端。"], translation: "小时候不认识月亮,叫它白玉盘。又怀疑是瑶台镜,飞在青云端。" },
  8.             { title: "风", author: "李峤", dynasty: "唐", lines: ["解落三秋叶,", "能开二月花。", "过江千尺浪,", "入竹万竿斜。"], translation: "能吹落三秋的叶,能开出二月的花。过江掀起千尺浪,入竹万竿都倾斜。" },
  9.             { title: "对韵歌", author: "佚名", dynasty: "清", lines: ["云对雨,雪对风。", "花对树,鸟对虫。", "山清对水秀,", "柳绿对桃红。"], translation: "云对雨,雪对风。花对树,鸟对虫。山清对水秀,柳绿对桃红。" },
  10.             { title: "数字诗", author: "佚名", dynasty: "清", lines: ["一片两片三四片,", "五片六片七八片。", "九片十片无数片,", "飞入梅花总不见。"], translation: "一片两片三四片,五片六片七八片。九片十片无数片,飞入梅花总不见。" },
  11.             { title: "一年之计在于春", author: "谚语", dynasty: "民", lines: ["一年之计在于春,", "一日之计在于晨。", "一寸光阴一寸金,", "寸金难买寸光阴。"], translation: "一年的计划在于春天,一天的计划在于早晨。一寸光阴一寸金,寸金难买寸光阴。" },
  12.             { title: "方向歌", author: "童谣", dynasty: "民", lines: ["早晨起来,面向太阳。", "前面是东,后面是西。", "左面是北,右面是南。"], translation: "早晨起来,面向太阳。前面是东,后面是西。左面是北,右面是南。" },
  13.             { title: "成语积累", author: "童蒙", dynasty: "民", lines: ["种瓜得瓜,种豆得豆。", "前人栽树,后人乘凉。", "千里之行,始于足下。", "百尺竿头,更进一步。"], translation: "种什么得什么,前人的付出让后人受益,走千里路要从脚下开始,不要满足现状要更进一步。" }
  14.         ]}
  15.     ];
复制代码



回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
有4副牌的拖拉机吗?谢谢

点评

a66
还没人发  详情 回复 发表于 6 天前
回复

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
本帖最后由 a66 于 2026-3-21 11:14 编辑
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>四副牌拖拉机</title>
  7.     <style>
  8.         * {
  9.             margin: 0;
  10.             padding: 0;
  11.             box-sizing: border-box;
  12.             font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
  13.         }

  14.         body {
  15.             background: linear-gradient(135deg, #1a2a3a, #0d1620);
  16.             color: #fff;
  17.             min-height: 100vh;
  18.             overflow-x: hidden;
  19.         }

  20.         .game-container {
  21.             max-width: 1600px;
  22.             margin: 0 auto;
  23.             padding: 20px;
  24.         }

  25.         .game-header {
  26.             text-align: center;
  27.             padding: 24px 20px;
  28.             margin-bottom: 20px;
  29.             background: rgba(255, 255, 255, 0.05);
  30.             border-radius: 20px;
  31.             box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  32.             backdrop-filter: blur(10px);
  33.             border: 1px solid rgba(255, 255, 255, 0.1);
  34.         }

  35.         .game-title {
  36.             font-size: 40px;
  37.             color: #ffd700;
  38.             text-shadow: 0 0 15px rgba(255, 215, 0, 0.6);
  39.             letter-spacing: 2px;
  40.         }

  41.         .tip-panel {
  42.             text-align: center;
  43.             padding: 16px;
  44.             background: rgba(255, 215, 0, 0.08);
  45.             border: 1px solid rgba(255, 215, 0, 0.4);
  46.             border-radius: 16px;
  47.             font-size: 18px;
  48.             color: #ffd700;
  49.             font-weight: bold;
  50.             margin-bottom: 20px;
  51.             box-shadow: 0 4px 20px rgba(255, 215, 0, 0.15);
  52.         }

  53.         .score-panel {
  54.             display: flex;
  55.             justify-content: space-around;
  56.             background: rgba(255, 255, 255, 0.05);
  57.             padding: 20px;
  58.             border-radius: 18px;
  59.             margin-bottom: 20px;
  60.             box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
  61.             backdrop-filter: blur(10px);
  62.             border: 1px solid rgba(255, 255, 255, 0.1);
  63.         }

  64.         .score-item {
  65.             text-align: center;
  66.             min-width: 120px;
  67.         }

  68.         .score-label {
  69.             font-size: 15px;
  70.             color: #ccc;
  71.             margin-bottom: 6px;
  72.         }

  73.         .score-num {
  74.             font-size: 30px;
  75.             font-weight: bold;
  76.             color: #ffd700;
  77.             text-shadow: 0 0 10px rgba(255, 215, 0, 0.4);
  78.         }

  79.         .suit-select {
  80.             display: flex;
  81.             justify-content: center;
  82.             gap: 18px;
  83.             margin-bottom: 20px;
  84.         }

  85.         .suit-btn {
  86.             width: 68px;
  87.             height: 68px;
  88.             font-size: 34px;
  89.             border-radius: 14px;
  90.             border: none;
  91.             background: rgba(255, 255, 255, 0.9);
  92.             box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  93.             cursor: pointer;
  94.             transition: all 0.25s ease;
  95.         }

  96.         .suit-btn:hover {
  97.             transform: scale(1.08);
  98.         }

  99.         .suit-btn.active {
  100.             transform: scale(1.12);
  101.             box-shadow: 0 0 20px #ffd700;
  102.             background: #ffd700;
  103.         }

  104.         .players-area {
  105.             display: grid;
  106.             grid-template-areas:
  107.                 ". top ."
  108.                 "left center right"
  109.                 ". bottom .";
  110.             grid-template-columns: 1fr 2.4fr 1fr;
  111.             gap: 22px;
  112.         }

  113.         .player {
  114.             background: rgba(255, 255, 255, 0.04);
  115.             border-radius: 20px;
  116.             padding: 18px;
  117.             border: 1px solid rgba(255, 255, 255, 0.08);
  118.             box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  119.             backdrop-filter: blur(10px);
  120.             transition: all 0.3s ease;
  121.         }

  122.         .player.active {
  123.             border-color: rgba(255, 215, 0, 0.6);
  124.             box-shadow: 0 0 25px rgba(255, 215, 0, 0.25);
  125.             background: rgba(255, 215, 0, 0.06);
  126.         }

  127.         .player.banker {
  128.             border-color: rgba(255, 80, 80, 0.6);
  129.             box-shadow: 0 0 25px rgba(255, 80, 80, 0.2);
  130.             background: rgba(255, 80, 80, 0.05);
  131.         }

  132.         .player-name {
  133.             text-align: center;
  134.             font-size: 18px;
  135.             margin-bottom: 16px;
  136.             color: #fff;
  137.             text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  138.         }

  139.         .player-top { grid-area: top; }
  140.         .player-left { grid-area: left; }
  141.         .player-right { grid-area: right; }
  142.         .player-bottom { grid-area: bottom; }

  143.         .center-area {
  144.             grid-area: center;
  145.             display: flex;
  146.             flex-direction: column;
  147.             align-items: center;
  148.             justify-content: center;
  149.         }

  150.         .play-area {
  151.             width: 420px;
  152.             height: 260px;
  153.             background: rgba(255, 255, 255, 0.06);
  154.             border-radius: 22px;
  155.             border: 2px dashed rgba(255, 215, 0, 0.4);
  156.             display: flex;
  157.             align-items: center;
  158.             justify-content: center;
  159.             flex-wrap: wrap;
  160.             gap: 10px;
  161.             padding: 20px;
  162.             margin-bottom: 20px;
  163.             box-shadow: 0 0 30px rgba(255, 215, 0, 0.1);
  164.         }

  165.         .cards-container {
  166.             display: flex;
  167.             flex-wrap: wrap;
  168.             gap: 7px;
  169.             justify-content: center;
  170.             max-height: 210px;
  171.             overflow-y: auto;
  172.             padding: 6px;
  173.         }

  174.         .poker-card {
  175.             width: 46px;
  176.             height: 68px;
  177.             background: linear-gradient(160deg, #ffffff, #f6f6f6);
  178.             color: #000;
  179.             border-radius: 8px;
  180.             display: flex;
  181.             flex-direction: column;
  182.             justify-content: space-between;
  183.             padding: 5px;
  184.             font-weight: bold;
  185.             cursor: pointer;
  186.             transition: transform 0.25s ease, box-shadow 0.25s ease;
  187.             border: 1px solid rgba(0,0,0,0.1);
  188.             box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
  189.             position: relative;
  190.         }

  191.         /* 标准纸质扑克牌背面样式 */
  192.         .poker-card.back {
  193.             background: linear-gradient(45deg, #1a237e, #d32f2f);
  194.             background-image: repeating-linear-gradient(
  195.                 45deg,
  196.                 rgba(255,255,255,0.1),
  197.                 rgba(255,255,255,0.1) 5px,
  198.                 rgba(0,0,0,0.1) 5px,
  199.                 rgba(0,0,0,0.1) 10px
  200.             );
  201.             cursor: default;
  202.             overflow: hidden;
  203.         }

  204.         .poker-card.back::before {
  205.             content: "";
  206.             position: absolute;
  207.             top: 50%;
  208.             left: 50%;
  209.             width: 20px;
  210.             height: 20px;
  211.             background: rgba(255,255,255,0.2);
  212.             border-radius: 50%;
  213.             transform: translate(-50%, -50%);
  214.         }

  215.         .poker-card.back:hover {
  216.             transform: none;
  217.             box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
  218.             z-index: auto;
  219.         }

  220.         .poker-card:hover {
  221.             transform: translateY(-10px) scale(1.06);
  222.             box-shadow: 0 12px 24px rgba(0, 0, 0, 0.35);
  223.             z-index: 10;
  224.         }

  225.         .poker-card.selected {
  226.             transform: translateY(-8px);
  227.             border: 3px solid #00d8ff;
  228.             box-shadow: 0 0 16px #00d8ff;
  229.             background: linear-gradient(160deg, #e0f7ff, #c7f2ff);
  230.         }

  231.         .poker-card.main {
  232.             border: 2px solid #ff4444;
  233.             box-shadow: 0 0 10px rgba(255, 68, 68, 0.4);
  234.         }

  235.         .poker-card.red {
  236.             color: #e53935;
  237.         }

  238.         .card-top, .card-bottom {
  239.             font-size: 14px;
  240.         }

  241.         .card-bottom {
  242.             align-self: flex-end;
  243.             transform: rotate(180deg);
  244.         }

  245.         .card-center {
  246.             font-size: 22px;
  247.             text-align: center;
  248.         }

  249.         .cards-container::-webkit-scrollbar {
  250.             width: 6px;
  251.         }
  252.         .cards-container::-webkit-scrollbar-thumb {
  253.             background: rgba(255, 215, 0, 0.4);
  254.             border-radius: 3px;
  255.         }

  256.         .control-panel {
  257.             text-align: center;
  258.             margin-top: 28px;
  259.             padding: 24px 20px;
  260.             background: rgba(255, 255, 255, 0.05);
  261.             border-radius: 20px;
  262.             box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
  263.             backdrop-filter: blur(10px);
  264.             border: 1px solid rgba(255, 255, 255, 0.1);
  265.         }

  266.         .btn {
  267.             padding: 14px 28px;
  268.             margin: 0 10px 10px;
  269.             font-size: 16px;
  270.             font-weight: 500;
  271.             border-radius: 14px;
  272.             border: none;
  273.             background: linear-gradient(145deg, #ffd700, #e6bc00);
  274.             color: #111;
  275.             cursor: pointer;
  276.             transition: all 0.25s ease;
  277.             box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  278.             letter-spacing: 1px;
  279.         }

  280.         .btn:hover {
  281.             transform: translateY(-3px);
  282.             box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
  283.             background: linear-gradient(145deg, #ffed4e, #ffd700);
  284.         }

  285.         .btn:disabled {
  286.             background: #444;
  287.             color: #888;
  288.             cursor: not-allowed;
  289.             transform: none;
  290.             box-shadow: none;
  291.         }

  292.         @media (max-width: 768px) {
  293.             .players-area {
  294.                 grid-template-areas: "top" "left" "center" "right" "bottom";
  295.                 grid-template-columns: 1fr;
  296.                 gap: 16px;
  297.             }
  298.             .game-title { font-size: 28px; }
  299.             .play-area { width: 92%; height: 200px; }
  300.             .poker-card { width: 40px; height: 60px; }
  301.             .btn { padding: 12px 20px; font-size: 14px; }
  302.         }
  303.     </style>
  304. </head>
  305. <body>
  306.     <div class="game-container">
  307.         <div class="game-header">
  308.             <h1 class="game-title">🎆 四副牌拖拉机🎆</h1>
  309.         </div>

  310.         <div class="tip-panel" id="tip-text">老哥,点【开始新游戏】咱们开干!</div>

  311.         <div class="suit-select" id="suit-select" style="display:none;">
  312.             <button class="suit-btn" data-suit="♠">♠</button>
  313.             <button class="suit-btn" data-suit="♥">♥</button>
  314.             <button class="suit-btn" data-suit="♣">♣</button>
  315.             <button class="suit-btn" data-suit="♦">♦</button>
  316.         </div>

  317.         <div class="score-panel">
  318.             <div class="score-item">
  319.                 <div class="score-label">庄家等级</div>
  320.                 <div class="score-num" id="banker-level">2</div>
  321.             </div>
  322.             <div class="score-item">
  323.                 <div class="score-label">闲家得分</div>
  324.                 <div class="score-num" id="player-score">0</div>
  325.             </div>
  326.             <div class="score-item">
  327.                 <div class="score-label">底牌数量</div>
  328.                 <div class="score-num" id="di-pai">12</div>
  329.             </div>
  330.             <div class="score-item">
  331.                 <div class="score-label">当前主牌</div>
  332.                 <div class="score-num" id="main-suit">2</div>
  333.             </div>
  334.         </div>

  335.         <div class="players-area">
  336.             <div class="player player-top" id="p-top">
  337.                 <div class="player-name">玩家2(上家)</div>
  338.                 <div class="cards-container" id="top-cards"></div>
  339.             </div>
  340.             <div class="player player-left" id="p-left">
  341.                 <div class="player-name">玩家3(对家)</div>
  342.                 <div class="cards-container" id="left-cards"></div>
  343.             </div>
  344.             <div class="center-area">
  345.                 <div class="play-area" id="play-area">
  346.                     <div style="color:gold; font-size:24px;">等待出牌</div>
  347.                 </div>
  348.                 <div style="color:gold; font-size:20px; text-shadow:0 0 10px gold;" id="main-info">主花色:未选择</div>
  349.             </div>
  350.             <div class="player player-right" id="p-right">
  351.                 <div class="player-name">玩家4(下家)</div>
  352.                 <div class="cards-container" id="right-cards"></div>
  353.             </div>
  354.             <div class="player player-bottom active" id="p-bottom">
  355.                 <div class="player-name">我(庄家)</div>
  356.                 <div class="cards-container" id="bottom-cards"></div>
  357.             </div>
  358.         </div>

  359.         <div class="control-panel">
  360.             <button class="btn" id="start-btn">✅ 开始新游戏</button>
  361.             <button class="btn" id="bury-btn" disabled>📥 埋底牌</button>
  362.             <button class="btn" id="hint-bury" disabled>💡 帮我选底</button>
  363.             <button class="btn" id="play-card" disabled>🃏 出牌</button>
  364.             <button class="btn" id="hint-play" disabled>💡 帮我出牌</button>
  365.             <button class="btn" id="pass-btn" disabled>⏭️ 不出</button>
  366.             <button class="btn" id="reset-btn">🔄 重置</button>
  367.         </div>
  368.     </div>

  369.     <script>
  370.         const cardTypes = ['♠','♥','♣','♦'];
  371.         const cardNumbers = ['2','3','4','5','6','7','8','9','10','J','Q','K','A'];
  372.         const numOrder = {'A':0,'K':1,'Q':2,'J':3,'10':4,'9':5,'8':6,'7':7,'6':8,'5':9,'4':10,'3':11,'2':12};

  373.         let game = {
  374.             phase: 'init',
  375.             mainLevel: '2',
  376.             mainSuit: null,
  377.             banker: 3,
  378.             bankerLevel: 2,
  379.             playerScore: 0,
  380.             players: [[],[],[],[]],
  381.             diPai: [],
  382.             selected: [],
  383.             roundCards: [],
  384.             leadSuit: null,
  385.             leadType: null,
  386.             currentPlayer: 3
  387.         };

  388.         function shuffle(a) {
  389.             for(let i=a.length-1;i>0;i--){
  390.                 const j=Math.floor(Math.random()*(i+1));
  391.                 [a[i],a[j]]=[a[j],a[i]];
  392.             }
  393.         }

  394.         function isMain(card) {
  395.             return card.num === game.mainLevel || card.type === game.mainSuit;
  396.         }

  397.         function sortCards(cards) {
  398.             return [...cards].sort((a,b)=>{
  399.                 const am = isMain(a), bm = isMain(b);
  400.                 if(am&&!bm)return -1; if(!am&&bm)return 1;
  401.                 if(a.type!==b.type)return ['♠','♥','♣','♦'].indexOf(a.type)-['♠','♥','♣','♦'].indexOf(b.type);
  402.                 return numOrder[a.num]-numOrder[b.num];
  403.             });
  404.         }

  405.         function getCardGroupType(cards) {
  406.             if(cards.length===1)return 'single';
  407.             const cnt = {};
  408.             cards.forEach(c=>cnt[c.num]=(cnt[c.num]||0)+1);
  409.             const vals = Object.values(cnt).sort((a,b)=>b-a);
  410.             const nums = Object.keys(cnt).sort((a,b)=>numOrder[a]-numOrder[b]);
  411.             let isTractor = true;
  412.             for(let i=1;i<nums.length;i++){
  413.                 if(numOrder[nums[i]]-numOrder[nums[i-1]]!==1)isTractor=false;
  414.             }
  415.             if(isTractor){
  416.                 if(vals.every(v=>v===2))return 'tractor';
  417.                 if(vals.every(v=>v===3))return 'tractor3';
  418.                 if(vals.every(v=>v===4))return 'tractor4';
  419.             }
  420.             if(vals[0]===4)return 'four';
  421.             if(vals[0]===3)return 'triple';
  422.             if(vals[0]===2)return 'pair';
  423.             return 'invalid';
  424.         }

  425.         function renderCard(card, idx){
  426.             const cls = isMain(card)?'poker-card main':'poker-card';
  427.             const red = card.type==='♥'||card.type==='♦'?'red':'';
  428.             return `<div class="${cls} ${red}" data-idx="${idx}" onclick="selectCard(${idx})">
  429.                 <div class="card-top">${card.num}</div>
  430.                 <div class="card-center">${card.type}</div>
  431.                 <div class="card-bottom">${card.num}</div>
  432.             </div>`;
  433.         }

  434.         // 渲染其他玩家牌背面
  435.         function renderBackCards(count){
  436.             let html = '';
  437.             for(let i=0;i<count;i++){
  438.                 html += '<div class="poker-card back"></div>';
  439.             }
  440.             return html;
  441.         }

  442.         function renderAll(){
  443.             // 上家、对家、下家:只显示背面
  444.             document.getElementById('top-cards').innerHTML = renderBackCards(game.players[0].length);
  445.             document.getElementById('left-cards').innerHTML = renderBackCards(game.players[1].length);
  446.             document.getElementById('right-cards').innerHTML = renderBackCards(game.players[2].length);
  447.             
  448.             // 自己:显示真实牌面
  449.             document.getElementById('bottom-cards').innerHTML =
  450.                 sortCards(game.players[3]).map((c,j)=>renderCard(c,j)).join('');

  451.             document.getElementById('banker-level').innerText=game.bankerLevel;
  452.             document.getElementById('player-score').innerText=game.playerScore;
  453.             document.getElementById('di-pai').innerText=game.diPai.length;
  454.             document.getElementById('main-info').innerText=game.mainSuit?`主花色:${game.mainSuit} ${game.mainLevel}`:'主花色:未选择';
  455.             document.querySelectorAll('.player').forEach((el,i)=>{
  456.                 el.classList.toggle('active',i===game.currentPlayer);
  457.                 el.classList.toggle('banker',i===game.banker);
  458.             });
  459.         }

  460.         function setTip(t){document.getElementById('tip-text').innerText=t;}

  461.         function selectCard(idx){
  462.             if(game.phase!=='bury'&&game.phase!=='play')return;
  463.             const card = document.querySelectorAll('#bottom-cards .poker-card')[idx];
  464.             if(!card)return;
  465.             card.classList.toggle('selected');
  466.             const found = game.selected.includes(idx);
  467.             if(found)game.selected=game.selected.filter(x=>x!==idx);
  468.             else game.selected.push(idx);
  469.         }

  470.         document.getElementById('hint-bury').onclick = () => {
  471.             if(game.phase !== 'bury') return;
  472.             document.querySelectorAll('.poker-card.selected').forEach(e=>e.classList.remove('selected'));
  473.             game.selected = [];
  474.             const hand = sortCards(game.players[3]);
  475.             const scoreValues = {'5':5,'10':10,'K':10};
  476.             const scored = hand.filter(c=>scoreValues[c.num]);
  477.             const nonMainNonScore = hand.filter(c=>!isMain(c)&&!scoreValues[c.num]);
  478.             let suggest = [];
  479.             if(nonMainNonScore.length>=12){
  480.                 suggest = nonMainNonScore.slice(0,12);
  481.             }else{
  482.                 suggest = [...nonMainNonScore,...scored].slice(0,12);
  483.             }
  484.             suggest.forEach(card=>{
  485.                 const idx = hand.findIndex(x=>x===card);
  486.                 if(idx!==-1) selectCard(idx);
  487.             });
  488.             setTip("✅ 帮你选好底啦!尽量埋副牌、不留分,放心埋!");
  489.         };

  490.         document.getElementById('hint-play').onclick = () => {
  491.             if(game.phase !== 'play' || game.currentPlayer !==3) return;
  492.             document.querySelectorAll('.poker-card.selected').forEach(e=>e.classList.remove('selected'));
  493.             game.selected = [];
  494.             const hand = sortCards(game.players[3]);
  495.             let suggest = [];

  496.             if(game.roundCards.length === 0){
  497.                 const mainCards = hand.filter(isMain);
  498.                 suggest = mainCards.length >= 1 ? [mainCards[0]] : [hand[0]];
  499.                 setTip("💡 第一次出牌,建议先出主牌,稳得住!");
  500.             }else{
  501.                 const needSuit = game.leadSuit;
  502.                 const needLen = game.roundCards[0].cards.length;
  503.                 const sameSuit = hand.filter(c=>c.type === needSuit);
  504.                 if(sameSuit.length >= needLen){
  505.                     suggest = sameSuit.slice(0, needLen);
  506.                     setTip("👉 有这花色,必须跟!我帮你选好了同花色!");
  507.                 }else{
  508.                     suggest = hand.slice(0, needLen);
  509.                     setTip("⚠️ 没这花色了,随便垫,我帮你挑几张垫!");
  510.                 }
  511.             }

  512.             suggest.forEach(card=>{
  513.                 const idx = hand.findIndex(x=>x===card);
  514.                 if(idx!==-1) selectCard(idx);
  515.             });
  516.         };

  517.         document.getElementById('start-btn').onclick=()=>{
  518.             let deck=[];
  519.             for(let d=0;d<4;d++)cardTypes.forEach(t=>cardNumbers.forEach(n=>deck.push({type:t,num:n})));
  520.             shuffle(deck);
  521.             game.players=[[],[],[],[]];
  522.             for(let i=0;i<4;i++)game.players[i]=deck.splice(0,51);
  523.             game.diPai=deck.splice(0,12);
  524.             game.phase='selectSuit';
  525.             game.playerScore=0;
  526.             document.getElementById('suit-select').style.display='flex';
  527.             document.getElementById('hint-bury').disabled = true;
  528.             document.getElementById('hint-play').disabled = true;
  529.             setTip("庄家请亮主!选个你最牛的花色当主!");
  530.             renderAll();
  531.         };

  532.         document.querySelectorAll('.suit-btn').forEach(btn=>{
  533.             btn.onclick=()=>{
  534.                 game.mainSuit=btn.dataset.suit;
  535.                 game.phase='bury';
  536.                 document.getElementById('suit-select').style.display='none';
  537.                 document.getElementById('bury-btn').disabled=false;
  538.                 document.getElementById('hint-bury').disabled = false;
  539.                 setTip("该埋底啦!选12张牌,点【帮我选底】更省事~");
  540.                 renderAll();
  541.             }
  542.         });

  543.         document.getElementById('bury-btn').onclick=()=>{
  544.             if(game.selected.length!==12){setTip("兄弟,必须选12张埋底,不多不少!");return;}
  545.             const sorted = sortCards(game.players[3]);
  546.             game.selected.sort((a,b)=>b-a).forEach(i=>{
  547.                 const card = sorted[i];
  548.                 const real = game.players[3].findIndex(c=>c===card);
  549.                 if(real!==-1)game.diPai.push(game.players[3].splice(real,1)[0]);
  550.             });
  551.             game.selected=[];
  552.             game.phase='play';
  553.             document.getElementById('bury-btn').disabled=true;
  554.             document.getElementById('hint-bury').disabled=true;
  555.             document.getElementById('play-card').disabled=false;
  556.             document.getElementById('hint-play').disabled=false;
  557.             document.getElementById('pass-btn').disabled=false;
  558.             setTip("✅ 埋底完成!开打!该你出牌啦~");
  559.             renderAll();
  560.         };

  561.         document.getElementById('play-card').onclick=()=>{
  562.             if(game.currentPlayer!==3||game.selected.length===0){setTip("先点牌再出牌啊老哥!");return;}
  563.             const sorted = sortCards(game.players[3]);
  564.             const cards = game.selected.map(i=>sorted[i]);
  565.             const type = getCardGroupType(cards);
  566.             if(type==='invalid'){setTip("兄弟,这牌型不对,出不了!");return;}

  567.             if(game.roundCards.length===0){
  568.                 game.leadSuit=cards[0].type;
  569.                 game.leadType=type;
  570.             }

  571.             cards.forEach(c=>{
  572.                 const real=game.players[3].findIndex(x=>x===c);
  573.                 if(real!==-1)game.players[3].splice(real,1);
  574.             });

  575.             game.roundCards.push({p:3,cards,type});
  576.             game.selected=[];
  577.             document.querySelectorAll('.poker-card.selected').forEach(x=>x.classList.remove('selected'));
  578.             showCards(cards);
  579.             nextPlayer();
  580.             renderAll();
  581.         };

  582.         function showCards(cards){
  583.             const area=document.getElementById('play-area');
  584.             area.innerHTML=cards.map(c=>`<div class="poker-card ${c.type=='♥'||c.type=='♦'?'red':''} ${isMain(c)?'main':''}">
  585.                 <div class="card-top">${c.num}</div><div class="card-center">${c.type}</div><div class="card-bottom">${c.num}</div>
  586.             </div>`).join('');
  587.         }

  588.         function nextPlayer(){
  589.             game.currentPlayer=(game.currentPlayer+1)%4;
  590.             if(game.currentPlayer===3){endRound();return;}
  591.             setTimeout(()=>{
  592.                 const p=game.currentPlayer;
  593.                 const hand=game.players[p];
  594.                 let play=[];
  595.                 if(game.roundCards.length===0){
  596.                     play=[hand.shift()];
  597.                     game.leadSuit=play[0].type;
  598.                     game.leadType='single';
  599.                 }else{
  600.                     const suitCards=hand.filter(c=>c.type===game.leadSuit);
  601.                     if(suitCards.length>=game.roundCards[0].cards.length){
  602.                         play=suitCards.slice(0,game.roundCards[0].cards.length);
  603.                         play.forEach(c=>{
  604.                             const i=game.players[p].findIndex(x=>x===c);
  605.                             if(i!==-1)game.players[p].splice(i,1);
  606.                         });
  607.                     }else{
  608.                         play=hand.splice(0,game.roundCards[0].cards.length);
  609.                     }
  610.                 }
  611.                 game.roundCards.push({p,cards:play,type:getCardGroupType(play)});
  612.                 showCards(play);
  613.                 game.currentPlayer=(game.currentPlayer+1)%4;
  614.                 setTip("轮到你啦,该你出牌!");
  615.                 renderAll();
  616.             },1000);
  617.         }

  618.         function endRound(){
  619.             let win=0, maxPower=-1;
  620.             let score=0;
  621.             game.roundCards.forEach(({cards})=>{
  622.                 cards.forEach(c=>{
  623.                     if(c.num==='5')score+=5;
  624.                     if(c.num==='10'||c.num==='K')score+=10;
  625.                 });
  626.             });

  627.             const power={tractor4:100,tractor3:90,four:80,tractor:70,triple:60,pair:50,single:40};
  628.             game.roundCards.forEach(({p,cards,type})=>{
  629.                 let pow=power[type]||0;
  630.                 if(isMain(cards[0]))pow+=20;
  631.                 if(pow>maxPower){maxPower=pow;win=p;}
  632.             });

  633.             if([0,2].includes(win))game.playerScore+=score;

  634.             const lastType=game.roundCards[win].type;
  635.             if(game.players.every(p=>p.length===0)){
  636.                 let diScore=0;
  637.                 game.diPai.forEach(c=>{
  638.                     if(c.num==='5')diScore+=5;
  639.                     if(c.num==='10'||c.num==='K')diScore+=10;
  640.                 });
  641.                 if(['pair','triple','four','tractor','tractor3','tractor4'].includes(lastType))diScore*=2;
  642.                 game.playerScore+=diScore;
  643.             }

  644.             game.roundCards=[];
  645.             game.leadSuit=null;
  646.             game.leadType=null;
  647.             document.getElementById('play-area').innerHTML=`<div style="color:gold; font-size:22px; text-shadow:0 0 10px gold">这墩玩家${win+1}拿了!</div>`;

  648.             if(game.players.every(p=>p.length===0)){
  649.                 if(game.playerScore>=400){
  650.                     setTip(`🏆 闲家干到${game.playerScore}分,破庄成功!庄家下台升级!`);
  651.                 }else{
  652.                     setTip(`✅ 闲家才${game.playerScore}分,没破庄!庄家继续坐庄!`);
  653.                 }
  654.                 game.phase='gameEnd';
  655.                 alert(document.getElementById('tip-text').innerText);
  656.             }else{
  657.                 game.currentPlayer=win;
  658.                 setTip(`这墩拿了${score}分,目前总分:${game.playerScore},继续干!`);
  659.             }
  660.             renderAll();
  661.         }

  662.         document.getElementById('pass-btn').onclick=()=>{setTip("🙅‍♂️ 我不出,你们上!");};
  663.         document.getElementById('reset-btn').onclick=()=>location.reload();
  664.         window.onload=renderAll;
  665.     </script>
  666. </body>
  667. </html>
复制代码
回复

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
本帖最后由 a66 于 2026-3-21 11:16 编辑
2013ertert 发表于 2026-3-21 09:37
有4副牌的拖拉机吗?谢谢

四副牌拖拉机.png

点评

谢谢 哈哈,其他人地也看到了,不好吧。  详情 回复 发表于 6 天前
回复

使用道具 举报

发表于 6 天前 来自手机 | 显示全部楼层
有没有单机版 游戏,感谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层

谢谢 哈哈,其他人地也看到了,不好吧。

点评

a66
已修正  详情 回复 发表于 6 天前
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层

谢谢分享
回复

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
2013ertert 发表于 2026-3-21 10:47
谢谢 哈哈,其他人地也看到了,不好吧。

已修正
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
谢谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
谢谢分享,下载玩玩。
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享好东东
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享,试试看
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
谢谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
感谢分享
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
好,有机会试试!!
回复

使用道具 举报

发表于 5 天前 | 显示全部楼层
感谢楼主辛苦分享!
回复

使用道具 举报

发表于 5 天前 | 显示全部楼层
有点意思,感谢分享
回复

使用道具 举报

发表于 4 天前 | 显示全部楼层
谢谢分享
回复

使用道具 举报

发表于 4 天前 | 显示全部楼层
感谢分享好东东
回复

使用道具 举报

发表于 4 天前 来自手机 | 显示全部楼层
多谢分享
回复

使用道具 举报

发表于 3 天前 | 显示全部楼层
太好啦,萬分感謝版主的無私發佈分享
回复

使用道具 举报

发表于 前天 07:44 | 显示全部楼层
这个以前比较喜欢玩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持| 无忧启动 ( 闽ICP备05002490号-1|闽公网安备35020302032614号 )

GMT+8, 2026-3-27 08:50

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表