编写一个俄罗斯方块
编写俄罗斯方块 思路。
1、创建容器数组,方块,
2、下落,左右移动,旋转,判断结束,消除。
定义一个20行10列的数组表示游戏区。初始这个数组里用0填充,1表示有一个方块,2表示该方块固定了,
然后随机出一个方块,操作左右转,触底变2后,再随机下一个方块,循环直到判定结束。

<template><div><div class="gamebox"><div class="table"><ul><li v-for="item in elsStore.gameArray">{{ item }}</li></ul></div><div class="next"><ul><li v-for="item in elsStore.nextArray">{{ item }}</li></ul><p>消除:{{ elsStore.score }}</p></div></div><div class="toolbar"><div><el-button type="success" @click="gameStart">开始</el-button><el-button type="success" @click="gameReset">重置</el-button></div></div></div>
</template><script setup lang="ts">
import useElsStore from '@/stores/els';
const elsStore = useElsStore();
elsStore.resetTable
//     // I:一次最多消除四层
//     // L(左右):最多消除三层,或消除二层
//     // O:消除一至二层
//     // S(左右):最多二层,容易造成孔洞
//     // Z(左右):最多二层,容易造成孔洞
//     // T:最多二层
let intervalDown: NodeJS.Timer;
const gameStart = () => {//  开始游戏  当前游戏中,需要先重置游戏,// 放置next,并开始游戏逻辑elsStore.randNext;intervalDown = setInterval(startDown, 1000);}
const gameReset = () => {clearInterval(intervalDown);elsStore.resetTable}const startDown = () => {console.log("down....");}</script><style scoped lang="scss">
.gamebox {display: flex;justify-content: flex-start;.next {margin-left: 20px;p {margin-top: 20px;}}
}.toolbar {display: flex;width: 100vw;justify-content: center;margin-top: 10px;}
</style>  
 
//定义关于counter的store
import { defineStore } from 'pinia'
import { enumStoreName } from "../index";
import { ElsTable } from '@/api/room/type';//defineStore 是返回一个函数 函数命名最好有use前缀,根据函数来进行下一步操作
const useElsStore = defineStore(enumStoreName.elsStore, {state: (): ElsTable => {return {// 主要区域gameArray: new Array<Array<number>>(),// 下一个图形nextArray: new Array<Array<number>>(),// 定义俄罗斯方块游戏区域大小rows: 20, columns: 10,// 对应值 0 空,1有活动方块 , 2有固定方块value: 0,// 游戏分数score: 0}},actions: {// 初始化界面resetTable() {this.gameArray = new Array<Array<number>>();this.nextArray = new Array<Array<number>>();// reset mainfor (let i = 0; i < this.rows; i++) {this.gameArray.push(new Array<number>());}for (let i = 0; i < this.gameArray.length; i++) {for (let j = 0; j < this.columns; j++) {this.gameArray[i].push(this.value);}}// reset nextfor (let i = 0; i < 4; i++) {this.nextArray.push(new Array<number>());}for (let i = 0; i < this.nextArray.length; i++) {for (let j = 0; j < 4; j++) {this.nextArray[i].push(this.value);}}},randNext(){}},getters: {getAddress(): string {return ""},},persist: {key: enumStoreName.elsStore,storage: localStorage,},
})export default useElsStore 
 
第二阶段:改版后的情况

1、编写ui部分
 <div><div class="gamebox"><div class="table"><ul><li v-for="item in elsStore.els.getShowPlate()  "><span v-for="x in item.split(',')"><div class="box" v-if="x != '0'":style="'background-color:' + elsStore.els.next_plate.color + ';'"></div></span></li></ul></div><div class="next"><div class="top"><ul><li v-for="item in elsStore.els.next_plate.currentString().split('@')"><span v-for="x in item.split(',')"><div class="box" v-if="x != '0'":style="'background-color:' + elsStore.els.next_plate.color + ';'"></div></span></li></ul><p>消除: {{ elsStore.els.score }}</p></div><div class="bottom"><div class="btn"><el-button type="success" @click="gameStart">开始</el-button><el-button type="success" @click="gameReset">重置</el-button></div></div></div></div><div class="toolbar"><div class="btn"><el-button type="success" @click="leftClick" :icon="ArrowLeftBold">左移</el-button><el-button type="success" @click="rightClick" :icon="ArrowRightBold">右移</el-button><el-button type="success" @click="rotateClick" :icon="Refresh">旋转</el-button><el-button type="success" @click="downClick" :icon="Refresh">下落</el-button></div> </div> </div> 
<style scoped lang="scss">
.gamebox {display: flex;justify-content: flex-start;.table {ul {width: 60vw;border: solid 1px;margin: 20px;li {display: flex;width: 60vw;span {width: 6vw;height: 6vw;.box {width: 100%;height: 100%;border: 1px solid #000;}}}}}.next {display: flex;flex-direction: column;justify-content: space-between;align-items: center;margin-top: 40px;.top {ul {width: 24vw;li {display: flex;width: 24vw;span {width: 6vw;height: 6vw;border: solid 1px;.box {width: 100%;height: 100%;}}}}}p {margin-top: 20px;}.bottom {margin-bottom: 148px;.btn {display: flex;flex-direction: column;align-items: flex-end;justify-content: space-around;button {margin-bottom: 5px;}}}}
}.toolbar {display: flex;width: 100vw;justify-content: center;margin-top: 10px;flex-direction: column;.btn {display: flex;justify-content: center;}}.el-button {height: 70px;
}
</style>  
主要逻辑部分
import { ArrowLeftBold, Refresh, ArrowRightBold } from '@element-plus/icons-vue'
import { GameControl } from "./class/GameControl";
import { reactive  } from "vue";const elsStore = reactive({els: new GameControl()
}) const rotateClick = () => {console.log("向右旋转");elsStore.els.rotate()
}
const leftClick = () => {elsStore.els.current_plate.position.x =(elsStore.els.current_plate.position.x > 0) ? elsStore.els.current_plate.position.x - 1 : 0}
const rightClick = () => {elsStore.els.current_plate.position.x =(elsStore.els.current_plate.position.x + elsStore.els.current_plate.getPlateSize().width < 10)? elsStore.els.current_plate.position.x + 1 : elsStore.els.current_plate.position.x}
const downClick = () => {elsStore.els.current_plate.position.y += 1
}const timers = () => {console.log("游戏循环开始");// 检查当前盘是否有重叠的,因为最后一步是让动块下降一格。// 因此,如果最后一步没有重叠,那么说明盘已经到底了,游戏结束// console.log('currentBox' + elsStore.els.current_plate.name, elsStore.els.current_plate.position.y);if (!elsStore.els.checkShowPlateIsOK()) {console.log("游戏结束");elsStore.els.started = false;return false}// 在Main盘面合法的情况下,需要检查即将触底或碰撞,就触发Lock更新if (elsStore.els.willPong()) {// console.log("====================Lock================");elsStore.els.lock_plate = elsStore.els.getShowPlate().join("@")// 消除elsStore.els.checkAndClear();// 负责下一块给当前动块,并随机一个下一块。elsStore.els.newCurrentPlate();} else {elsStore.els.current_plate.position.y += 1;}setTimeout(() => {if (elsStore.els.started) { timers(); }}, 500);};const gameStart = () => {console.log('游戏开始');if (elsStore.els.started) {return false;}elsStore.els.next_plate = elsStore.els.newRndPlate()elsStore.els.started = truetimers();}const gameReset = () => {console.log('重置游戏');elsStore.els = new GameControl()elsStore.els.started = false}
 
可以看到主要是循环部分。然后就是调gameControl部分
 
import { Config } from "../config";
import { Plate } from "./Plate";export class GameControl {next_plate: Plate;current_plate: Plate;lock_plate: string;started: boolean;score: number;constructor() {this.next_plate = this.newRndPlate()this.current_plate = this.copyNextToCurrent();this.lock_plate = Config.defuaultLockPlatethis.started = falsethis.score = 0this.init()}init() {// 初始化游戏 console.log("初始化游戏");// 显示一个等待方块,并等待用户按下开始按钮。 }// 生成一个随机盘子newRndPlate() {return new Plate(Plate.PlateType[Math.floor(Math.random() * 6)]);}// 复制下一个盘子到当前盘子private copyNextToCurrent(): Plate {let plate = new Plate(this.next_plate.name);plate.position.x = 3plate.position.y = 0return plate}// 合并盘子 ,用给定的Plate和Lock进行合并,不用检查是否重叠private margePlate(plate: Plate) {let tmp_plate = plate.currentStringMax().split("@");let lockList = this.lock_plate.split("@");let newLockList: string[] = []// console.log({ tmp_plate, lockList, newLockList });// 跟lock合并for (let i = 0; i < lockList.length; i++) {let lockListi = lockList[i].split(",");let tmp_platei = tmp_plate[i].split(",");let newLockLine: string[] = []for (let j = 0; j < lockListi.length; j++) {newLockLine.push("" + eval(lockListi[j] + '+' + tmp_platei[j]))}newLockList.push(newLockLine.join(","))}// console.log({ newLockList });return newLockList;}// 检查给定数组是否有重叠private checkMainOK(main: string[]): boolean {for (let i = 0; i < main.length; i++) {const boxList = main[i].split(",")for (let j = 0; j < boxList.length; j++) {if (eval(boxList[j]) > 1) {return false;}}}return true;}willPong(): boolean {let tmp_plate = new Plate(this.current_plate.name);tmp_plate.position.x = this.current_plate.position.xtmp_plate.position.y = this.current_plate.position.y + 1tmp_plate.direction = this.current_plate.directionlet height = tmp_plate.getPlateSize().height;if (tmp_plate.position.y + height > 20) {return true}let newLockList = this.margePlate(tmp_plate);return !this.checkMainOK(newLockList);}getShowPlate(): string[] {if (!this.started) {return this.lock_plate.split("@")}// console.log("====================");// console.log({ current_plate:this.current_plate,lock_plate:this.lock_plate});let newLockList = this.margePlate(this.current_plate);// console.log({ newLockList});// // 跟lock合并// for (let i = 0; i < lockList.length; i++) {//     let lockListi = lockList[i].split(",");//     let tmp_platei = tmp_plate[i].split(",");//     let newLockLine: string[] = []//     for (let j = 0; j < lockListi.length; j++) {//         newLockLine.push("" + eval(lockListi[j] + '+' + tmp_platei[j]))//     }//     newLockList.push(newLockLine.join(","))// }// for (let i = 0; i < lockList.length; i++) {//     if (i < tmp_plate.length) {//         let lockListi = lockList[i].split(",");//         let tmp_platei = tmp_plate[i].split(",");//         let newLockLine: string[] = []//         for (let j = 0; j < lockListi.length; j++) {//             newLockLine.push("" + eval(lockListi[j] + '+' + tmp_platei[j]))//         }//         newLockList.push(newLockLine.join(","))//     } else {//         let lockListi = lockList[i].split(",");//         let newLockLine: string[] = []//         for (let j = 0; j < lockListi.length; j++) {//             newLockLine.push(lockListi[j])//         }//         newLockList.push(newLockLine.join(","))//     }// }return newLockList;}// 检查getShowPlate是否有大于1的块checkShowPlateIsOK() {return this.checkMainOK(this.getShowPlate());}//   newCurrentPlate 函数newCurrentPlate() {this.current_plate = this.copyNextToCurrent();this.next_plate = this.newRndPlate()}// 旋转后的dirrotate() {// 如果超界或重叠就不让旋转 仅下部分超界就不让。this.current_plate.direction = (this.current_plate.direction + 1) % 4if (this.current_plate.position.y + this.current_plate.getPlateSize().height > 20 || (!this.checkShowPlateIsOK())) {this.current_plate.direction = (this.current_plate.direction - 1) % 4}}// 消除checkAndClear() {// 更新locklet lockList = this.lock_plate.split("@");let tmpList:string[] = []lockList.forEach((item ) => {if(item!="1,1,1,1,1,1,1,1,1,1"){tmpList.push(item)}});for (let index = 0; index < 20-tmpList.length; index++) {this.score ++tmpList = ['0,0,0,0,0,0,0,0,0,0'].concat(tmpList)}this.lock_plate = tmpList.join("@");}} 
最后就是2个小类
export class Box {color: string;icon: string;disabled: boolean;constructor(color: string     ) { this.color = color; this.icon = "Grid"; this.disabled = true; } } 
const  defuaultLockPlate: string = "0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0@0,0,0,0,0,0,0,0,0,0"; export const  Config =  {defuaultLockPlate}
 
import { Box } from "./Box";interface Pos {x: number;y: number;
}
export class Plate extends Box {// I:一次最多消除四层  (状态横竖2种)// L(左):L最多消除三层,或消除二层  (状态横竖4种)// R(右):反L最多消除三层,或消除二层   (状态横竖4种)// O:消除一至二层  (状态1种)// S(左右):最多二层,容易造成孔洞  (状态横竖2种)// Z(左右):最多二层,容易造成孔洞 (状态横竖2种)// T:最多二层 (状态横竖4种)name: string;// 字符串数组arrString: string[];// currentString: string;// 位置position: Pos;// 方向direction: number;// 是否锁住lock: boolean;static PlateType = ["I", "L", "O", "S", "Z", "T"]constructor(name: string) {let colors = ["red", "yellow", "blue", "green", "purple", "orange"];switch (name) {case "I":super(colors[0]);this.name = name;this.arrString = ["0,0,0,0@1,1,1,1@0,0,0,0@0,0,0,0","0,1,0,0@0,1,0,0@0,1,0,0@0,1,0,0","0,0,0,0@1,1,1,1@0,0,0,0@0,0,0,0","0,1,0,0@0,1,0,0@0,1,0,0@0,1,0,0"]break;case "L":super(colors[1]);this.name = name;this.arrString = ["0,1,1,1@0,1,0,0@0,0,0,0@0,0,0,0","0,0,1,0@1,1,1,0@0,0,0,0@0,0,0,0","0,1,0,0@0,1,0,0@0,1,1,0@0,0,0,0","0,1,1,0@0,0,1,0@0,0,1,0@0,0,0,0"]break;case "O":super(colors[2]);this.name = name;this.arrString = ["0,1,1,0@0,1,1,0@0,0,0,0@0,0,0,0","0,1,1,0@0,1,1,0@0,0,0,0@0,0,0,0","0,1,1,0@0,1,1,0@0,0,0,0@0,0,0,0","0,1,1,0@0,1,1,0@0,0,0,0@0,0,0,0",]break;case "S":super(colors[3]);this.name = name;this.arrString = ["0,0,1,1@0,1,1,0@0,0,0,0@0,0,0,0","0,1,0,0@0,1,1,0@0,0,1,0@0,0,0,0","0,0,1,1@0,1,1,0@0,0,0,0@0,0,0,0","0,1,0,0@0,1,1,0@0,0,1,0@0,0,0,0"]break;case "Z":super(colors[4]);this.name = name;this.arrString = ["0,1,1,0@0,0,1,1@0,0,0,0@0,0,0,0","0,0,1,0@0,1,1,0@0,1,0,0@0,0,0,0","0,1,1,0@0,0,1,1@0,0,0,0@0,0,0,0","0,0,1,0@0,1,1,0@0,1,0,0@0,0,0,0"]break;default: //Tsuper(colors[5]);this.name = name;this.arrString = ["0,0,1,0@0,1,1,0@0,0,1,0@0,0,0,0","0,0,1,0@0,1,1,1@0,0,0,0@0,0,0,0","0,1,0,0@0,1,1,0@0,1,0,0@0,0,0,0","0,1,1,1@0,0,1,0@0,0,0,0@0,0,0,0"]break;}this.position = {x: -1,y: -1}this.direction = Math.floor(Math.random() * 4)this.lock = falseconsole.log('创建了一个' + this.name + ' 颜色:' + this.color + ' 方向:' + this.direction);}// 4*4大小public currentString(): string {return this.arrString[this.direction]}//  精简块的内容 最小 化块public currentStringMin(): string {let plateStr = this.arrString[this.direction]let plates: string[] = [];// 去掉多余的 行plateStr.split("@").forEach((item) => {if (eval(item.replace(/,/g, "+")) > 0) {plates.push(item);}});// 去掉多余的 列 就是裁剪前面的0和后面的0// 计算是块的valueCount 如果少了,就不能裁剪。const countPlateValue = (plates: string[]) => {let tmpPlateList = plates.map((item) => {const sum = item.split(",").reduce(function (prev, cur) {return eval(prev + "+" + cur);});return sum})return tmpPlateList.reduce(function (prev, cur) {return eval(prev + "+" + cur);});}// console.log("test value", countPlateValue(plates));// 裁剪前面的0 const cuxsuff = (plates: string[]): string[] => {if (plates[0].split(",").length == 1) return plates// 尝试裁剪 ,如果长度为1,就不用裁剪了let tmpPlateList: string[] = plates.map((item) => {let t = item.split(",")t.shift()return t.join(",")})if (countPlateValue(tmpPlateList) == countPlateValue(plates)) {return cuxsuff(tmpPlateList)} else {return plates}}// 裁剪后面的0const cuxdiff = (plates: string[]): string[] => {if (plates[0].split(",").length == 1) return plates// 尝试裁剪 ,如果长度为1,就不用裁剪了let tmpPlateList: string[] = plates.map((item) => {let t = item.split(",")t.pop()return t.join(",")})if (countPlateValue(tmpPlateList) == countPlateValue(plates)) {return cuxdiff(tmpPlateList)} else {return plates}}const remainingPlates = cuxdiff(cuxsuff(plates)).join("@");return remainingPlates;}// 格式化成 Mian大小 的块public currentStringMax(): string {let currentString = this.currentStringMin()  let maxY = 20 - this.getPlateSize().height;let maxX = 10 - this.getPlateSize().width;this.position.x = this.position.x >= maxX ? maxX : this.position.x;this.position.y = this.position.y >= maxY ? maxY : this.position.y;let x = this.position.xlet y = this.position.ylet tmpPlateList = currentString.split("@").map((item) => {let prefix: string[] = [];let suffix: string[] = [];for (let i = 0; i < x; i++) {prefix.push("0")}for (let i = 0; i < 10 - item.split(",").length - x; i++) {suffix.push("0")}return prefix.concat(item.split(",").concat(suffix)).join(",");});for (let index = 0; index < y; index++) {tmpPlateList = ['0,0,0,0,0,0,0,0,0,0'].concat(tmpPlateList)}for (let index = 0; index < 20 - y - currentString.split("@").length; index++) {tmpPlateList = tmpPlateList.concat(['0,0,0,0,0,0,0,0,0,0'])}return tmpPlateList.join("@")}// 获取长和高public getPlateSize(): { width: number; height: number; } {return {width: this.currentStringMin().split("@")[0].split(",").length,height: this.currentStringMin().split("@").length}}} 
最后是完整的源码下 http s://gitcode.net/ldy889/game-els 项目删掉了一些没用的东西,只保留了核心代码,需要自己去除一些错误。比如修改路径,无效的引入。
相关文章:
编写一个俄罗斯方块
编写俄罗斯方块 思路。 1、创建容器数组,方块, 2、下落,左右移动,旋转,判断结束,消除。 定义一个20行10列的数组表示游戏区。初始这个数组里用0填充,1表示有一个方块,2表示该方块固…...
认识容器,走进Docker
文章目录 容器技术简介容器的核心技术容器平台技术容器的支持技术 Docker理念Docker安装配置阿里云镜像加速器 容器技术简介 一切在云端,万物皆容器,说到容器,大家都会想到Docker,Docker现在几乎是容器的代名词,什么是Docker&…...
初始web
华子目录 前后端与全栈BS架构网页开发原则前端三剑客初始htmlhtml的基本框架如何使用vscode创建网页网页基本框架html基本标签 前后端与全栈 前端:给用户看的内容 – 荧幕前(负责显示) 后端:在后台处理数据 – 荧幕后(负责处理) …...
JVM中释放内存的三种方法
判断是否需要垃圾回收可以采用分析。 1标记--清除算法 分为两个阶段,标记和清除,先利用可达性分型标记还存活的对象,之后将没有被标记的对象删除,这样容易生成空间碎片,而且效率不稳定 标记阶段: 标记阶段…...
图床项目进度(一)——UI首页
1. 前言 前面我不是说了要做一个图床吗,现在在做ui。 我vue水平不够高,大部分参考b站项目照猫画虎。 vue实战后台 我使用ts,vite,vue3进行了重构。 当然,我对这些理解并不深刻,许多代码都是游离于表面&am…...
vue3父子组件相互调用方法详解
vue3父子组件相互调用方法详解 1、前言2、父组件调用子组件方法2.1 子组件Child.vue2.2 父组件Father.vue 3、子组件调用父组件方法3.1 父组件Father.vue3.2 子组件Child.vue 1、前言 在vue3项目开发中,我们常常会遇到父子组件相互调用的场景,下面以set…...
Java之接口
作者简介: zoro-1,目前大一,正在学习Java,数据结构等 作者主页: zoro-1的主页 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 Java之接口 接口的概念语法规则接口特性接口使用案…...
QT学习笔记-QT5.15编译及安装谷歌拼音输入法(QtInputMethod_GooglePinyin)
QT学习笔记-QT5.15编译及安装谷歌拼音输入法(QtInputMethod_GooglePinyin) 0、背景1、环境2、下载QtInputMethod_GooglePinyin源码3、使用MinGW64构建套件编译3.1 编译QtInputMethod_GooglePinyin源码3.2、部署tgtsmlInputContextPlugin输入法插件3.3、运…...
python 使用 pdf2image 库将PDF转换为图片
在 Ubuntu 上实现网络穿透:手把手教你搭建FRPS服务器 初环境步骤一:安装pdf2image库步骤二:导入必要的库步骤三:指定PDF文件路径步骤四:将PDF转换为图片步骤五:保存图像为图片文件完整代码运行结果 在数字化…...
kubernetes(namespace、pod、deployment、service、ingress)
NameSpace NameSpace名称空间 用来隔离资源,但是不隔离网络 使用命令行: kubectl create ns hello #创建 kubectl delete ns hello #删除 kubectl get ns #查看使用配置文件: vi hello.yamlapiVersion: v1 kind: Namespace metadata:name…...
深度学习loss变为nan的问题
在网上查了一些资料,但是这个情况和网上都不太一样。前100epoch能正常训练,loss缓慢下降,精度缓慢增大,但是突然loss就Nan了,我想应该不是样本问题也不是梯度爆炸或者loss中有除0吧,毕竟都训练了100epoch了…...
音视频 ffplay命令-主要选项
选项说明-x width强制显示宽带-y height强制显示高度-video_size size帧尺寸 设置显示帧存储(WxH格式),仅适用于类似原始YUV等没有包含帧大小(WxH)的视频-pixel_format format格式设置像素格式-fs以全屏模式启动-an禁用音频(不播放声音)-vn禁…...
深入浅出Pytorch函数——torch.nn.init.dirac_
分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...
[Go版]算法通关村第十三关青铜——数字数学问题之统计问题、溢出问题、进制问题
这里写自定义目录标题 数字统计专题题目:数组元素积的符号思路分析:无需真计算,只需判断负数个数是奇是偶复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( 1 ) O(1) O(1)Go代码 题目:阶乘尾数0的个数思路分析&am…...
GPT-4一纸重洗:从97.6%降至2.4%的巨大挑战
斯坦福大学和加州大学伯克利分校合作进行的一项 “How Is ChatGPTs Behavior Changing Over Time?” 研究表明,随着时间的推移,GPT-4 的响应能力非但没有提高,反而随着语言模型的进一步更新而变得更糟糕。 研究小组评估了 2023 年 3 月和 20…...
大数据Flink学习圣经:一本书实现大数据Flink自由
学习目标:三栖合一架构师 本文是《大数据Flink学习圣经》 V1版本,是 《尼恩 大数据 面试宝典》姊妹篇。 这里特别说明一下:《尼恩 大数据 面试宝典》5个专题 PDF 自首次发布以来, 已经汇集了 好几百题,大量的大厂面试…...
什么是微服务?
2.微服务的优缺点 优点 单一职责原则每个服务足够内聚,足够小,代码容易理解,这样能聚焦一个指定的业务功能或业务需求;开发简单,开发效率提高,一个服务可能就是专一的只干一件事;微服务能够被小…...
【C++入门到精通】C++入门 —— 容器适配器、stack和queue(STL)
阅读导航 前言stack1. stack概念2. stack特点3. stack使用 queue1. queue概念2. queue特点3. queue使用 容器适配器1. 什么是适配器2. STL标准库中stack和queue的底层结构3. STL标准库中对于stack和queue的模拟实现⭕stack的模拟实现⭕stack的模拟实现 总结温馨提示 前言 文章…...
系统架构设计专业技能 · 软件工程之需求工程
系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA(一)【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估(二)【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…...
2023国赛数学建模E题思路模型代码 高教社杯
本次比赛我们将会全程更新思路模型及代码,大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
