- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Titletitle>
- <style type="text/css">
- #box1 table{
- border: 0px;
- border-collapse: collapse;
- cursor: pointer;
- }
-
- #box1 th {
- border: 0px;
- border-collapse: collapse;
- cursor: pointer;
- }
-
- #box1 td{
- border: 1px solid #000;
- border-collapse: collapse;
- cursor: pointer;
- }
-
-
- #box2 table{
- border-collapse: collapse;
- border: 0px;
- }
-
- #box2 th {
- border-collapse: collapse;
- border: 0px;
- }
-
- #box2 td{
- border-collapse: collapse;
- border: 1px solid transparent;
- border-radius:20px;
- }
-
- .color_human{
- background-color: white;
- }
-
- .color_machine{
- background-color: black;
- }
-
- .color_machine_win{
- background-color: red;
- }
-
- .color_human_win{
- background-color: green;
- }
-
- #box1{
- position: absolute;
- left: 100px;
- top: 100px;
- border: 0px;
- background-color: gray;
- }
-
- #box2{
- position: absolute;
- left: 110px;
- top: 110px;
- border: 0px;
- }
- style>
- head>
- <body>
- <div id="box1">div>
- <div id="box2">div>
- body>
- <script type="text/javascript">
- var map_code_td = new Map();
- var map_code_color = new Map();
- var map_code_score = new Map();
- var win = false;
- var color_human = "color_human";
- var color_machine = "color_machine"
- var codes_win = [];
- var color_blank = "xxx";
- var row_count = 20;
- var col_count = 20;
-
- // 辅助帮助显示横竖纹的底色棋盘,没有任何事件和业务逻辑
- function initBox1( ) {
- var table = document.createElement("table");
- table.rules = 'all' ;
- for (var rowNum = 1; rowNum <= row_count; rowNum++) {
- var tr = document.createElement("tr");
- for (var colNum = 1; colNum <= col_count; colNum++) {
- var td = document.createElement("td");
- td.width = 20;
- td.height = 20;
- tr.appendChild(td);
- }
- table.appendChild(tr);
- }
- document.getElementById( "box1" ).appendChild(table);
- }
-
- function initBox2( ) {
- var table = document.createElement("table");
- table.rules = 'all' ;
- for (var rowNum = 1; rowNum <= row_count; rowNum++) {
- var tr = document.createElement("tr");
- for (var colNum = 1; colNum <= col_count; colNum++) {
- var td = document.createElement("td");
- td.width = 20;
- td.height = 20;
- tr.appendChild(td);
-
- var code = rowNum + "_" + colNum;
- map_code_td.set( code,td );
- map_code_color.set( code,color_blank );
- }
- table.appendChild(tr);
- }
- document.getElementById( "box2" ).appendChild(table);
- table.addEventListener( "click", clickChess );
- }
-
- initBox1( );
- initBox2( );
-
- // 获取到点击的 td,如果该人类落子,则将td的颜色改为 人类棋子颜色,否则该机器落子,将颜色改为机器棋子颜色
- var shouldHumanPoint = true;
- function clickChess(){
- if( win ){
- return;
- }
- if( !shouldHumanPoint ){
- alert("稍等,机器落子后您再落子!");
- return;
- }
- var td = event.srcElement;
- var rowNum = td.parentElement.rowIndex + 1;
- var colNum = td.cellIndex + 1;
- if( isAlreadyFillPoint( rowNum,colNum ) ){
- alert( "该位置已落子" );
- return;
- }
-
- // 执行人类落子操作
- td.className = color_human;
- var code = rowNum + "_" + colNum;
- map_code_color.set( code,color_human );
- shouldHumanPoint = false;
-
- // 人类落子后检测是否胜利
- winCheck();
- if( win ){
- highlightFiveWinCodes( true );
- alert("人类胜利");
- return;
- }
-
- window.setTimeout(function(){
- // 机器开始落子
- machinePoint();
-
- // 机器落子后检测是否胜利
- winCheck();
- if( win ){
- highlightFiveWinCodes( false );
- alert("机器胜利");
- }
- },1000);
- }
-
- // 高亮5个连成线的棋子
- function highlightFiveWinCodes( humanWin ){
- for(var i=0;i<5;i++){
- var td = map_code_td.get( codes_win[i] );
- if( humanWin ){
- td.className = "color_human_win";
- }else{
- td.className = "color_machine_win";
- }
- }
- }
-
- // 机器落子操作
- function machinePoint(){
- // 首先检查人类是否存在机器不拦则人类必胜的情况,比如存在人类的 "空白白白空空"两端的 空的数量满足一端>=1 ,一端>1,则机器必须落在 "白白白"的两端
- // 空白白白空空、空空白白白空
- // 人类必胜检测
- // 人类必胜的六连子,检测到有,则机器落在六连子的最后一个子上
- var sixCodes = humanMustWinCheck();
- if( sixCodes ){
- console.log("检测到存在人类的必胜六连子,试图拦截:");
- console.log(sixCodes);
- var code = sixCodes[5];
- var td = map_code_td.get( code );
- td.className = color_machine;
- map_code_color.set( code,color_machine );
- shouldHumanPoint = true;
- return;
- }
-
- // 机器开始落子,需要找到一个得分最高的格子开始落子
- // 从下面 row_count * col_count 格子中找到得分最高的一个格子
- var maxScore = 0;
- var rowNum_maxScore = 0;
- var colNum_maxScore = 0;
- for( var rowNum = 1;rowNum <= row_count;rowNum++ ){
- for( var colNum = 1;colNum <= col_count;colNum++ ){
- if( isAlreadyFillPoint( rowNum,colNum ) ){
- // 该位置已经落子了,不考虑
- continue;
- }
- var score = calculateScore( rowNum, colNum );
- if( score > maxScore ){
- maxScore = score;
- rowNum_maxScore = rowNum;
- colNum_maxScore = colNum;
- }
- }
- }
-
- console.log( "机器应该落在" + rowNum_maxScore + "行" + colNum_maxScore + "列,得分:" + maxScore );
- var code = rowNum_maxScore + "_" + colNum_maxScore;
- var td = map_code_td.get( code );
- td.className = color_machine;
- map_code_color.set( code,color_machine );
- shouldHumanPoint = true;
- }
-
- // 检测指定位置是否已经落子了
- function isAlreadyFillPoint( rowNum,colNum ){
- var code = rowNum + "_" + colNum;
- var color = map_code_color.get( code );
- if( color == color_human || color == color_machine ){
- return true;
- }
- return false;
- }
-
- // 得分表,该程序的精髓,其实本程序未使用任何算法,只是使用了这个得分表,写这个得分表的人比较厉害,程序厉不厉害也是取决于得分表设计的精不精妙
- function calculateScoreForForHumanMachineColorCount( count_humanColor,count_machineColor){
- if( count_humanColor > 0 && count_machineColor > 0 ){
- return 0;
- }else if( count_humanColor == 0 && count_machineColor == 0 ){
- return 7;
- }else if( count_humanColor == 0 && count_machineColor == 1 ){
- return 35;
- }else if( count_humanColor == 0 && count_machineColor == 2 ){
- return 800;
- }else if( count_humanColor == 0 && count_machineColor == 3 ){
- return 15000;
- }else if( count_humanColor == 0 && count_machineColor == 4 ){
- return 800000;
- }else if( count_humanColor == 1 && count_machineColor == 0 ){
- return 15;
- }else if( count_humanColor == 2 && count_machineColor == 0 ){
- return 400;
- }else if( count_humanColor == 3 && count_machineColor == 0 ){
- return 1800;
- }else if( count_humanColor == 4 && count_machineColor == 0 ){
- return 100000;
- }else{
- return 0;
- }
- }
-
- // 为该五连子计算得分
- function calculateScoreForFiveCodes( fiveCodes ){
- // 统计人类棋子和机器棋子的个数
- var count_humanColor = 0;
- var count_machineColor = 0;
- for( var i=0;i<5;i++ ){
- var code = fiveCodes[i];
- var color = map_code_color.get( code );
- if( !color ){
- // 可能由于传递的 fiveCodes 不是有效的五连子导致的,比如 "16_1"、"-1_2"等,因为前面未进行最大最小合法角标的限制
- return 0;
- }
- if( color == color_human ){
- count_humanColor++;
- }else if( color == color_machine ){
- count_machineColor++;
- }
- }
- return calculateScoreForForHumanMachineColorCount( count_humanColor, count_machineColor );
- }
-
- function calculateScore(rowNum, colNum){
- var totalScore = 0;
- // 该格子所在行( 左-->右:行不变,列++ )
- // 统计该格子作为第1、2、3、4、5个子时候的五连子的得分之和
- for( var i=0; i<5; i++){
- var fiveCodes = [];
- fiveCodes.push( rowNum + "_" + ( colNum + 0 - i ) );
- fiveCodes.push( rowNum + "_" + ( colNum + 1 - i ) );
- fiveCodes.push( rowNum + "_" + ( colNum + 2 - i ) );
- fiveCodes.push( rowNum + "_" + ( colNum + 3 - i ) );
- fiveCodes.push( rowNum + "_" + ( colNum + 4 - i ) );
- totalScore += calculateScoreForFiveCodes( fiveCodes );
- }
-
- // 该格子所在列( 上->下:行++,列不变 )
- // 统计该格子作为第1、2、3、4、5个子时候的五连子的得分之和
- for( var i=0; i<5; i++){
- var fiveCodes = [];
- fiveCodes.push( ( rowNum + 0 - i ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 1 - i ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 2 - i ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 3 - i ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 4 - i ) + "_" + colNum );
- totalScore += calculateScoreForFiveCodes( fiveCodes );
- }
-
- // 该格子所在正斜线( 左下-->右上:行--,列++ )
- // 统计该格子作为第1、2、3、4、5个子时候的五连子的得分之和
- for( var i=0; i<5; i++){
- var fiveCodes = [];
- fiveCodes.push( ( rowNum + i - 0 ) + "_" + ( colNum + 0 - i ) );
- fiveCodes.push( ( rowNum + i - 1 ) + "_" + ( colNum + 1 - i ) );
- fiveCodes.push( ( rowNum + i - 2 ) + "_" + ( colNum + 2 - i ) );
- fiveCodes.push( ( rowNum + i - 3 ) + "_" + ( colNum + 3 - i ) );
- fiveCodes.push( ( rowNum + i - 4 ) + "_" + ( colNum + 4 - i ) );
- totalScore += calculateScoreForFiveCodes( fiveCodes );
- }
-
- // 该格子所在反斜线( 左上-->右下:行++,列++ )
- // 统计该格子作为第1、2、3、4、5个子时候的五连子的得分之和
- for( var i=0; i<5; i++){
- var fiveCodes = [];
- fiveCodes.push( ( rowNum + 0 - i ) + "_" + ( colNum + 0 - i ) );
- fiveCodes.push( ( rowNum + 1 - i ) + "_" + ( colNum + 1 - i ) );
- fiveCodes.push( ( rowNum + 2 - i ) + "_" + ( colNum + 2 - i ) );
- fiveCodes.push( ( rowNum + 3 - i ) + "_" + ( colNum + 3 - i ) );
- fiveCodes.push( ( rowNum + 4 - i ) + "_" + ( colNum + 4 - i ) );
- totalScore += calculateScoreForFiveCodes( fiveCodes );
- }
- return totalScore;
- }
-
- function winCheck(){
- if( win ){
- return;
- }
- // 检查全部的五连子,是否存在五个全是人类棋子或者五个全是机器棋子
- // 检查全部列上的五连子
- winCheck_col()
- if( win ){
- return;
- }
-
- // 检查全部行上的五连子
- winCheck_row();
- if( win ){
- return;
- }
-
- // 检查全部正斜线上的五连子
- winCheck_forwardSlash();
- if( win ){
- return;
- }
-
- // 检查全部反斜线上的五连子
- winCheck_backSlash();
- if( win ){
- return;
- }
- }
-
- function winCheck_forwardSlash(){
- // 列--,行++
- for( rowNum=1;rowNum<=row_count;rowNum++ ){
- for( colNum=1;colNum<=col_count;colNum++ ){
- var codes = [];
- codes.push( rowNum + "_" + colNum );
- codes.push( ( rowNum + 1 ) + "_" + ( colNum - 1 ) );
- codes.push( ( rowNum + 2 ) + "_" + ( colNum - 2 ) );
- codes.push( ( rowNum + 3 ) + "_" + ( colNum - 3 ) );
- codes.push( ( rowNum + 4 ) + "_" + ( colNum - 4 ) );
- if( isAllTargetColor( codes,color_human ) || isAllTargetColor( codes,color_machine ) ){
- win = true;
- }
- if( win ){
- for(var i=0;i<5;i++){
- codes_win.push( codes[i] );
- }
- return;
- }
- }
- }
- }
-
- function winCheck_backSlash(){
- // 列++,行++
- for( rowNum=1;rowNum<=row_count;rowNum++ ){
- for( colNum=1;colNum<=col_count;colNum++ ){
- var fiveCodes = [];
- fiveCodes.push( rowNum + "_" + colNum );
- fiveCodes.push( ( rowNum + 1 ) + "_" + ( colNum + 1 ) );
- fiveCodes.push( ( rowNum + 2 ) + "_" + ( colNum + 2 ) );
- fiveCodes.push( ( rowNum + 3 ) + "_" + ( colNum + 3 ) );
- fiveCodes.push( ( rowNum + 4 ) + "_" + ( colNum + 4 ) );
- if( isAllTargetColor( fiveCodes,color_human ) || isAllTargetColor( fiveCodes,color_machine ) ){
- // 都是人类棋子 或者 机器棋子,表示已经分出胜负了
- win = true;
- }
- if( win ){
- for( var i=0;i<5;i++ ){
- codes_win.push( fiveCodes[i] );
- }
- return;
- }
- }
- }
- }
-
- function winCheck_col(){
- // 检查全部列是否存在五连子
- // 列不变,行++
- for( var colNum=1;colNum<=col_count;colNum++ ){
- for( var rowNum=1;rowNum<=row_count;rowNum++ ){
- var fiveCodes = [];
- fiveCodes.push( rowNum + "_" + colNum );
- fiveCodes.push( ( rowNum + 1 ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 2 ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 3 ) + "_" + colNum );
- fiveCodes.push( ( rowNum + 4 ) + "_" + colNum );
- if( isAllTargetColor( fiveCodes,color_human ) || isAllTargetColor( fiveCodes,color_machine ) ){
- // 已经分出胜负了
- win = true;
- }
- if( win ){
- for( var i=0;i<5;i++ ){
- codes_win.push( fiveCodes[i] );
- }
- return;
- }
- }
- }
- }
-
- function winCheck_row(){
- // 行不变,列++
- for( var rowNum=1;rowNum<=row_count;rowNum++ ){
- for( var colNum=1;colNum<=col_count;colNum++ ){
- var codes = [];
- codes.push( rowNum + "_" + colNum );
- codes.push( rowNum + "_" + ( colNum + 1 ) );
- codes.push( rowNum + "_" + ( colNum + 2 ) );
- codes.push( rowNum + "_" + ( colNum + 3 ) );
- codes.push( rowNum + "_" + ( colNum + 4 ) );
- if( isAllTargetColor( codes,color_human ) || isAllTargetColor( codes,color_machine ) ){
- // 已经分出胜负了
- win = true;
- }
- if( win ){
- for( var i=0;i<5;i++ ){
- codes_win.push( codes[i] );
- }
- return;
- }
- }
- }
- }
-
- // 检查五连子是否都是指定的颜色
- function isAllTargetColor( fiveCodes,targetColor ){
- for( var i = 0;i<5;i++ ){
- var code = fiveCodes[i];
- var color = map_code_color.get( code );
- if( !color || color != targetColor ){
- return false;
- }
- }
- return true;
- }
-
- // 人类必胜检测
- // 检查人类是否存在机器不拦则人类必胜的情况,比如存在人类的 "空白白白空空"两端的 空的数量满足一端>=1 ,一端>1,则机器必须落在 "白白白"的两端
- function humanMustWinCheck(){
- // 全部行的 人类必胜检测
- var sixCodes = humanMustWinCheck_allRow();
- if( sixCodes ){
- return sixCodes;
- }
-
- // 全部列的 人类必胜检测
- sixCodes = humanMustWinCheck_allCol();
- if( sixCodes ){
- return sixCodes;
- }
-
- // 全部正斜线的 人类必胜检测
- sixCodes = humanMustWinCheck_allForwardSlash();
- if( sixCodes ){
- return sixCodes;
- }
-
- // 全部反斜线的 人类必胜检测
- sixCodes = humanMustWinCheck_allBackSlash();
- if( sixCodes ){
- return sixCodes;
- }
- }
-
- // 全部行的 人类必胜检测
- function humanMustWinCheck_allRow(){
- for( var rowNum=1;rowNum<=row_count;rowNum++ ){
- // 对当前行进行 人类必胜检测
- var sixCodes = humanMustWinCheck_row( rowNum );
- if( sixCodes ){
- return sixCodes;
- }
- }
- return null;
- }
-
- // 对当前行进行人类必胜检测
- function humanMustWinCheck_row( rowNum ){
- // 遍历当前行的全部六连子,检测是否存在 "空白白白空空"、"空空白白白空"
- for( var colNum=1;colNum<=col_count;colNum++ ){
- var codes = [];
- codes.push( rowNum + "_" + colNum );
- codes.push( rowNum + "_" + ( colNum + 1 ) );
- codes.push( rowNum + "_" + ( colNum + 2 ) );
- codes.push( rowNum + "_" + ( colNum + 3 ) );
- codes.push( rowNum + "_" + ( colNum + 4 ) );
- codes.push( rowNum + "_" + ( colNum + 5 ) );
- if( isHumanMushWinSixCodes( codes ) ){
- return codes;
- }
- }
- return null;
- }
-
- // 检查是否是人类必胜六连子
- function isHumanMushWinSixCodes( sixCodes ){
- var color1 = map_code_color.get( sixCodes[0] );
- var color2 = map_code_color.get( sixCodes[1] );
- var color3 = map_code_color.get( sixCodes[2] );
- var color4 = map_code_color.get( sixCodes[3] );
- var color5 = map_code_color.get( sixCodes[4] );
- var color6 = map_code_color.get( sixCodes[5] );
- if( !( color1 && color2 && color3 && color4 && color5 && color6 ) ){
- return false;
- }
- if( ( color1 == color_blank &&
- color2 == color_blank &&
- color3 == color_human &&
- color4 == color_human &&
- color5 == color_human &&
- color6 == color_blank ) ||
- ( color1 == color_blank &&
- color2 == color_human &&
- color3 == color_human &&
- color4 == color_human &&
- color5 == color_blank &&
- color6 == color_blank ) ){
- return true;
- }else{
- return false;
- }
- }
-
- // 当前列的人类必胜六连子检测
- function humanMustWinCheck_allCol(colNum){
- for( var rowNum=1;rowNum<=row_count;rowNum++ ){
- var codes = [];
- codes.push( rowNum + "_" + colNum );
- codes.push( ( rowNum + 1 ) + "_" + colNum );
- codes.push( ( rowNum + 2 ) + "_" + colNum );
- codes.push( ( rowNum + 3 ) + "_" + colNum );
- codes.push( ( rowNum + 4 ) + "_" + colNum );
- codes.push( ( rowNum + 5 ) + "_" + colNum );
- if( isHumanMushWinSixCodes( codes ) ){
- return codes;
- }
- }
- return null;
- }
-
- // 全部正斜线的 人类必胜检测
- function humanMustWinCheck_allForwardSlash(){
- for(var rowNum=1;rowNum<=row_count;rowNum++){
- // 当前正斜线的 人类必胜检测
- var sixCodes = humanMustWinCheck_forwardSlash(rowNum,1);
- if( sixCodes ){
- return sixCodes;
- }
- }
- for(var colNum=1;colNum<=col_count;colNum++){
- // 当前正斜线的 人类必胜检测
- var sixCodes = humanMustWinCheck_forwardSlash(row_count,colNum);
- if( sixCodes ){
- return sixCodes;
- }
- }
- return null;
- }
-
- // 当前正斜线的 人类必胜检测
- function humanMustWinCheck_forwardSlash( fromRowNum,fromColNum ){
- var large = row_count;
- if( col_count > large ){
- large = col_count;
- }
- for(var i=0;i
- var codes = [];
- codes.push( ( fromRowNum - i ) + "_" + ( fromColNum + i ) );
- codes.push( ( fromRowNum - i - 1 ) + "_" + ( fromColNum + i + 1 ) );
- codes.push( ( fromRowNum - i - 2 ) + "_" + ( fromColNum + i + 2 ) );
- codes.push( ( fromRowNum - i - 3 ) + "_" + ( fromColNum + i + 3 ) );
- codes.push( ( fromRowNum - i - 4 ) + "_" + ( fromColNum + i + 4 ) );
- codes.push( ( fromRowNum - i - 5 ) + "_" + ( fromColNum + i + 5 ) );
- if( isHumanMushWinSixCodes( codes ) ){
- return codes;
- }
- }
- return null;
- }
-
- // 全部反斜线的 人类必胜检测
- function humanMustWinCheck_allBackSlash(){
- for(var colNum=1;colNum<=col_count;colNum++){
- // 当前反斜线的 人类必胜检测
- var sixCodes = humanMustWinCheck_backSlash( 1,colNum );
- if( sixCodes ){
- return sixCodes;
- }
- }
- for(var rowNum=1;rowNum<=row_count;rowNum++){
- // 当前反斜线的 人类必胜检测
- var sixCodes = humanMustWinCheck_backSlash( rowNum,1 );
- if( sixCodes ){
- return sixCodes;
- }
- }
- return null;
- }
-
- // 行、列、正斜线、反斜线上的几个子的行号、列号增长的趋势规则(即++、--)可以添加到一个数组中,每次从数组中取
- // 当前反斜线的 人类必胜检测
- function humanMustWinCheck_backSlash(fromRowNum,fromColNum){
- var large = row_count;
- if( col_count > large ){
- large = col_count;
- }
- for( var i=0;i
- var codes = [];
- codes.push( ( fromRowNum + i ) + "_" + ( fromColNum + i ) );
- codes.push( ( fromRowNum + i + 1 ) + "_" + ( fromColNum + i + 1 ) );
- codes.push( ( fromRowNum + i + 2 ) + "_" + ( fromColNum + i + 2 ) );
- codes.push( ( fromRowNum + i + 3 ) + "_" + ( fromColNum + i + 3 ) );
- codes.push( ( fromRowNum + i + 4 ) + "_" + ( fromColNum + i + 4 ) );
- codes.push( ( fromRowNum + i + 5 ) + "_" + ( fromColNum + i + 5 ) );
- if( isHumanMushWinSixCodes( codes ) ){
- return codes;
- }
- }
- return null;
- }
- script>
- html>
-
相关阅读:
Java#6(类和对象及封装)
【LeetCode-中等题】347. 前 K 个高频元素
K8S中的某个容器突然出现内存和CPU占用过高的情况解决办法
一文读懂UTF-8的编码规则
vue @cliick.stop @click.prevent @click.self
真实感渲染:课程介绍
将编译过的C++库迅速部署在Visual Studio新项目中
【Docker】深入理解Docker:一种革新性的容器技术
【JAVA程序设计】(C00090) 基于SSM+Vue的宠物医院预约挂号平台
大家都在“跪求”的Spring响应式微服务PDF蓝光版,简直羡慕了!
-
原文地址:https://blog.csdn.net/heshiyuan1406146854/article/details/134079015