Screeps Arena 游戏基础教程

  • 一. 游戏内教程汉化
    • 1. 循环和导入(Loop and Import)
    • 2. 简单移动(Simple move)
    • 3. 首次攻击(First Attack)
    • 4. 爬虫的身体部分(Creeps Bodies)
    • 5. 存储和转移 (Store and Transfer)
    • 6. 地形 (Terrain)
    • 7. 生产爬虫(Spawn Creeps)
    • 8. 收割能源(Harvest Energy)
    • 9. 建设(Construction)
    • 10. 最终测试(Final Test)

Screeps Arena 是一款纯编程的RTS游戏(即时战略游戏),通过编写JavaScript(或其他语言)代码,控制从采集资源、生产单位、建造、移动、攻击的各种操作和应变逻辑,来让自己的战略运行起来,和其他的代码成果进行对局。

一. 游戏内教程汉化

1. 循环和导入(Loop and Import)

欢迎来到本教程,您将学习如何通过编码发挥爬虫竞技场 (Screeps Arena) 的基础知识。

你通过在本地文件夹中编写代码来玩游戏,游戏内的编辑器不好使,所有我们推荐你们使用一些其他的代码编辑器,例如vscode来编写代码。

循环:
当您点击PLAY按钮时,这些文件被提交给服务器。如果你的代码中没有语法错误,游戏就会开始,你就可以观看了。你不能在游戏期间更改提交的代码,比赛几秒钟后就结束了之后,你可以用任何速度观看。

每一个回合(或者我们称之为tick),游戏都会运行你的主函数 loop() 。该函数在main.mjs中被定义:

export function loop() {
    // Your code goes here
}

这个函数中的所有内容都将被反复执行,直到游戏结束。

导入:
有一个特殊的函数getTicks(),您可以调用它来确定当前的刻度是多少。为了调用它,你必须将它从/game/utils模块导入到你的代码中:

import { getTicks } from 'game/utils';

export function loop() {
    console.log('Current tick:', getTicks());
}

有许多方法和对象可以通过这种方式导入。请参阅文档了解。console.log()输出游戏控制台面板中的任何值,以便您可以调试和检查正在运行的代码。你不需要导入这个函数,它是全局可用的。

让我们开始:
在教程的第一步,我们没有任何游戏对象,游戏地图完全是空的。完成这一步所要的就是打印循环的一些信息。只需要将上面的代码复制粘贴到你的main.mjs文件中,然后点击PLAY按钮运行。
在这里插入图片描述


2. 简单移动(Simple move)

每个爬虫可以做各种动作,显然它可以移动。

creep.moveTo(target);

这个命令会让你的爬虫向目标移动一步,如果你在每次循环迭代中都执行它,你的爬虫就会一直移动到目的地。(在调用此函数时立即执行,但只能在循环函数完成之后执行移动。)

从代码访问你的爬虫,有一个特殊的函数叫做getObjectsByPrototype( ) ,它返回一个数组,其中包含所有具有给定原型或类的游戏对象。你可以像下面这样选择游戏中的所有爬虫:

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep);
}

在本教程的步骤中,我们有一个Flag对象,它也有它的原型名称。

最终目标:使用移动的方法让你的爬虫踩到旗子上。

代码如下:

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep);
    let flags = getObjectsByPrototype(Flag);
    creeps[0].moveTo(flags[0]);
}

3. 首次攻击(First Attack)

Screeps Arena是一款多人PvP游戏,你的爬虫将会和对手的爬虫战斗,所有让我们来简单学习一下攻击。

如何判断哪些是你的爬虫,使用JavaScript标准的Array.filter( )Array.find( )方法返回给定条件的元素数组。

filter( ) 方法返回提供的数组中满足所提供测试函数的所有元素的数组。

const words = ['spray', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter((word) => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]

find() 方法返回提供的数组中满足所提供测试函数的第一个元素。

const array1 = [5, 12, 8, 130, 44];
const found = array1.find((element) => element > 10);
console.log(found);
// Expected output: 12

在下面的例子中,可以基于爬虫的属性来查找指定爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';

export function loop() {
    var myCreep = getObjectsByPrototype(Creep).find(creep => creep.my);
    var enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);
}

现在我们可以使用attack方法攻击敌人了,当它无法到达目标时,他将返回ERR_NOT_IN_RANGE的错误信息,所以你需要先使用moveTo:

if(myCreep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
    myCreep.moveTo(enemyCreep);
}

本节最终目标:消灭敌方爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';
import { ERR_NOT_IN_RANGE } from 'game/constants';

export function loop() {
    let myCreep = getObjectsByPrototype(Creep).find(creep => creep.my);
    let enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);
    if(myCreep.attack(enemyCreep) === ERR_NOT_IN_RANGE) {
        myCreep.moveTo(enemyCreep);
    }
}

4. 爬虫的身体部分(Creeps Bodies)

你可以调用爬虫的很多函数来完成某个行为,但是并非所有函数都可以用于某个爬虫。爬虫可以调用什么函数取决于它的身体部位。你可以检查他的body属性,它是一个数组,其中数组每个元素代表某种类型的一个主体部分:

MOVE:使爬虫移动。
ATTACK:允许它近战范围内攻击。
RANGED_ATTACK:允许它攻击3格外的目标。
HEAL:允许治疗它自己或另一个爬虫。
WORK:可以建造建筑或收集能量。
CARRY:增加爬虫携带资源的能力,身上可以携带更多的资源。
TOUGH :没有任何效果。

if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
    // this creep has ATTACK body parts
}

Array..some() 是 JavaScript 中用于数组的方法之一,它用于检查数组中是否至少有一个元素满足指定的条件。这个方法会遍历数组的每个元素,直到找到一个满足条件的元素,然后立即返回 true。如果没有找到满足条件的元素,则返回 false。

array.some(callback(element[, index[, array]])[, thisArg])

参数说明:
callback:一个用于测试每个元素的函数,它可以接受三个参数:
element:当前正在处理的数组元素。
index(可选):当前正在处理的元素的索引。
array(可选):调用 some 方法的数组本身。
thisArg(可选):可选参数,函数执行时的 this 值。

每一个身体部位都会使爬虫的攻击力提高100点。当爬虫受到伤害时,他的身体部分也会受到伤害,如果该部分的数值被攻击清零了,它就会失去该部分的功能。同一类型的身体部位越多,这种类型的效果就越强。

现在,本教程步骤中我们有3种不同的部位:ATTACKRANGED_ATTACKHEAL的爬虫。只有协调好对手的行动,你才能打败他们。

为了做到这一点,使用与前一个教程步骤相同的方法,但根据他们的身体部位区分他们的行动,伤害发送者应该使用不同的方法(attackrangedAttack)进行伤害,治疗者应该使用heal方法治疗你受伤的爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';
import { ERR_NOT_IN_RANGE, ATTACK, RANGED_ATTACK, HEAL } from 'game/constants';

export function loop() {
    let myCreeps = getObjectsByPrototype(Creep).filter(creep => creep.my);
    let enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);

    for(let creep of myCreeps) {
        if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
            if(creep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
                creep.moveTo(enemyCreep);
            }
        }
        if(creep.body.some(bodyPart => bodyPart.type == RANGED_ATTACK)) {
            if(creep.rangedAttack(enemyCreep) == ERR_NOT_IN_RANGE) {
                creep.moveTo(enemyCreep);
            }
        }
        if(creep.body.some(bodyPart => bodyPart.type == HEAL)) {
            let myDamagedCreeps = myCreeps.filter(i => i.hits < i.hitsMax);
            if(myDamagedCreeps.length > 0) {
                if(creep.heal(myDamagedCreeps[0]) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(myDamagedCreeps[0]);
                }
            }
        }
    }
}

for...of 语句执行一个循环,该循环处理来自可迭代对象的值序列。可迭代对象包括内置对象的实例,例如 Array、String、TypedArray、Map、Set、NodeList(以及其他 DOM 集合),还包括 arguments 对象、由生成器函数生成的生成器,以及用户定义的可迭代对象。

const array1 = ['a', 'b', 'c'];
for (const element of array1) {
  console.log(element);
}
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"

5. 存储和转移 (Store and Transfer)

在不同的区域,有不同的可用资源。但是有一种常见的资源类型RESOURCE_ENERGY,用来建造建筑、生产爬虫等各种活动。

塔(Tower)可以造成50点的范围攻击伤害,尽管它的效率随着距离的增加而降低。在本教程的步骤中,我们将使用能量来给塔充能,以击败敌人。

tower.attack(target);

塔每次射击消耗10个能量单位。为了给它装载能量,你需要使用一个将能量传递给它的爬虫。

creep.transfer(tower, RESOURCE_ENERGY);

从哪里获得能量?附近有一个容器(Container),它的store有一些能量。你可以移动爬虫去容器中回收能量:

creep.withdraw(container, RESOURCE_ENERGY);

当塔内有足够能量时,他会攻击并摧毁目标。

如果你使用我们的示例代码,请注意我们现在是如何以不同的方式导入内容的(不是特别定义他们,而是从/game模块导入整个命名空间。)用哪种导入的写法,根据自己的喜好来:

import { prototypes, utils, constants } from 'game';

export function loop() {
    const tower = utils.getObjectsByPrototype(prototypes.StructureTower)[0];
    if(tower.store[constants.RESOURCE_ENERGY] < 10) {
        let myCreep = utils.getObjectsByPrototype(prototypes.Creep).find(creep => creep.my);
        if(myCreep.store[constants.RESOURCE_ENERGY] == 0) {
            let container = utils.getObjectsByPrototype(prototypes.StructureContainer)[0];
            myCreep.withdraw(container, constants.RESOURCE_ENERGY);
        } else {
            myCreep.transfer(tower, constants.RESOURCE_ENERGY);
        }
    } else {
        let target = utils.getObjectsByPrototype(prototypes.Creep).find(creep => !creep.my);
        tower.attack(target);
    }
}

6. 地形 (Terrain)

游戏中5种地形:平原地形、天然的坚不可摧的墙壁、建造的可摧毁的墙、沼泽、道路。

沼泽和道路上移动与爬虫的重量相关联。每个爬虫的身体部位,除了MOVE,都会增加了他的重量。(一个空的CARRY 身体部位不会增加重量),但如果爬虫体内有资源将会增加它的身体重量。每个MOVE部位能增加爬虫的移动速度。如果的MOVE身体部位和所有其他身体部位数量数量相同时,你的爬虫将勉勉强强能够在平原地形上移动。否则小于的话,他会感到疲劳,动弹不得。

但是有相同身体部位的爬虫在沼泽上,它会变得更加疲劳,并且每5 tick才只能移动一次。为了让你每次tick都能移动,你的爬虫将需要5倍以上的MOVE部件。

相反,道路减少了你的爬虫对MOVE部件的需求。例如,如果你的爬虫有10个负重的身体部位,你在道路上移动就只需要5个MOVE身体部件就可以使这个爬虫每次循环移动。

注意,当你需要使用寻路算法从一个数组中找到一个位置最近的对象时,可以使用findClosestByPath 函数。

let flags = getObjectsByPrototype(Flag);
let closestFlag = creep.findClosestByPath(flags);

在本节教程中,你只需要将每个爬虫移动到相应的旗子。代码如下:

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep).filter(i => i.my);
    let flags = getObjectsByPrototype(Flag);
    for(let creep of creeps) {
        let flag = creep.findClosestByPath(flags);
        creep.moveTo(flag);
    }
}

7. 生产爬虫(Spawn Creeps)

当你在一个有Spawn结构的竞技场上玩游戏时,你可以使用spawnCreep方法创建新的爬虫。您需要将新爬虫的主体定义为包含其主体部分的数组。

你想要刷出的爬虫越大,它消耗的能量就越多,具体数值如下:
MOVE:50能量
ATTACK:80能量
RANGED_ATTACK:150能量
HEAL:250能量
WORK:100能量
CARRY:50能量
TOUGH :10能量

spawnCreep方法返回一个稍后使用的Creep实例。

let creep = mySpawn.spawnCreep([MOVE, ATTACK]).object;

你甚至可以在loop函数之外定义变量,以便在tick之间使用它们:

let creep;
export function loop() {
    if(!creep) {
        creep = mySpawn.spawnCreep([MOVE, ATTACK]).object;
    }
}

请注意,您可以为这个爬虫对象分配任何属性,如果你想要给爬虫分布一些目标、角色或其他数据,这可能会很有用:

creep.target = flag;

在本教程步骤中,你有一个刷出和两个旗帜。目标:刷出两个爬虫,并将每个爬虫移动到每个旗帜上。

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag, StructureSpawn } from 'game/prototypes';
import { MOVE } from 'game/constants';

let creep1, creep2;

export function loop() {
    let mySpawn = getObjectsByPrototype(StructureSpawn)[0];
    let flags = getObjectsByPrototype(Flag);

    if(!creep1) {
        creep1 = mySpawn.spawnCreep([MOVE]).object;
    } else {
        creep1.moveTo(flags[0]);

        if(!creep2) {
            creep2 = mySpawn.spawnCreep([MOVE]).object;
        } else {
            creep2.moveTo(flags[1]);
        }
    }
}

8. 收割能源(Harvest Energy)

能源可以以不同的形式获得,它可以存储在容器中,但是也可以从Sources中收获,如果你的爬虫有work身体部位,那么它就可以使用使用harvest方法从Source提取一些能量。

creep.harvest(source);

你的爬虫必须靠近能源才能执行这个动作。它拥有的WORK身体部位越多,每一次从能源处提取的能量就越多。能源中的能量储备是无限的,一段时间后会重新刷满。

本节目标:收割和转移1000能量到Spawn

import { prototypes, utils, constants } from 'game';

export function loop() {
    let creep = utils.getObjectsByPrototype(prototypes.Creep).find(i => i.my);
    let source = utils.getObjectsByPrototype(prototypes.Source)[0];
    let spawn = utils.getObjectsByPrototype(prototypes.StructureSpawn).find(i => i.my);

    if(creep.store.getFreeCapacity(constants.RESOURCE_ENERGY)) {
        if(creep.harvest(source) == constants.ERR_NOT_IN_RANGE) {
            creep.moveTo(source);
        }
    } else {
        if(creep.transfer(spawn, constants.RESOURCE_ENERGY) == constants.ERR_NOT_IN_RANGE) {
            creep.moveTo(spawn);
        }
    }
}

9. 建设(Construction)

你不仅可以生成爬虫,还可以建造建筑!只需要一点能量和一个工人就能完成工作。

首先,使用createConstructionSite函数放置一个名为StructureTower在某个地方,你需要指定建筑的坐标和原型。

import { createConstructionSite } from 'game/utils';
import { StructureTower } from 'game/prototypes';

export function loop() {
    let constructionSite = createConstructionSite({x: 50, y: 55}, StructureTower).object;
}

你带着能量的爬虫必须接近建筑工地建造他:

creep.build(constructionSite);

每一次成功的建造行动都会消耗你的爬虫体内存储的一些能量,所以你的爬虫需要在你的能量供应处和建筑工地之间来回穿梭。

本节目标:建造一座塔。

import { prototypes, utils } from 'game';
import { RESOURCE_ENERGY, ERR_NOT_IN_RANGE } from 'game/constants';

export function loop() {
    const creep = utils.getObjectsByPrototype(prototypes.Creep).find(i => i.my);
    if(!creep.store[RESOURCE_ENERGY]) {
        const container = utils.findClosestByPath(creep, utils.getObjectsByPrototype(prototypes.StructureContainer));
        if(creep.withdraw(container, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
            creep.moveTo(container);
        }
    } else {
        const constructionSite = utils.getObjectsByPrototype(prototypes.ConstructionSite).find(i => i.my);
        if(!constructionSite) {
            utils.createConstructionSite(50,55, prototypes.StructureTower);
        } else {
            if(creep.build(constructionSite) == ERR_NOT_IN_RANGE) {
                creep.moveTo(constructionSite);
            }
        }
    }
}

10. 最终测试(Final Test)

现在你已经学会了如何控制爬虫,攻击敌人,使用能量,产生新的爬虫,建造新的结构。看起来你已经为最终测试做好了准备!

在本教程步骤中,你有一个Spawn和一个Source。有一群敌人的爬虫,你要产生更多的爬虫,并击败他们。这次我们甚至不会给你提供示例代码! 当你完成本教程,你可以移动到真正的PvP竞技场,并开始在多人模式下与其他人战斗。祝你好运!

目标:在攻击中幸存下来,杀死所有的敌人并完成教程。

本节就不写示例代码了,每个人都有每个人自己的写法,正好做一个小小测试。

游戏官方已经提供了比较全面的vscode代码补全功能了,你只要用vscode打开对应模式的文件夹(注意不要单打开文件,而应该打开文件夹!)就能使用代码补全来编写代码了。然后在第一行加上// @ts-nocheck就不会报错啦。

以后打算再汉化一下官方的API文档,敬请期待,希望能帮到大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/510726.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

dataloader numworkers

numworkers是加载数据的额外cpu数量&#xff08;也可以看成额外的进程&#xff09;。可以理解是&#xff1a; dataset中的getitem只能得到单个数据&#xff0c; 而numworker设置后是同时加载numwork个数据到RAM中&#xff0c;当需要数据时&#xff0c;不会重新执行getiem的方法…

代码随想录算法训练营第四十二天 | 卡码网46. 携带研究材料、416. 分割等和子集

代码随想录算法训练营第四十二天 | 卡码网46. 携带研究材料、416. 分割等和子集 卡码网46. 携带研究材料题目解法 416. 分割等和子集题目解法 感悟 卡码网46. 携带研究材料 题目 解法 题解链接 二维数组 # include <bits/stdc.h> using namespace std;int n, bagweig…

读取信息boot.bin和xclbin命令

bootgen读Boot.bin命令 johnjohn-virtual-machine:~/project_zynq/kv260_image_ubuntu22.04$ bootgen -read BOOT-k26-starter-kit-202305_2022.2.bin xclbinutil读xclbin命令 johnjohn-virtual-machine:~/project_zynq/kv260_image_ubuntu22.04$ xclbinutil -i kv260-smartca…

【Vue】vue3简介与环境配置

文章目录 项目编码规范什么是 Vue&#xff1f;安装node环境nvm针对node版本惊醒管理的工具 项目编码规范 组合式API Typescript setup(语法糖) 什么是 Vue&#xff1f; Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;…

Linux系统下安装jdk与tomcat【linux】

一、yum介绍 linux下的jdk安装以及环境配置&#xff0c;有两种常用方法&#xff1a; 1.使用yum一键安装。 2.手动安装&#xff0c;在Oracle官网下载好需要的jdk版本&#xff0c;上传解压并配置环境。 这里介绍第一种方法&#xff0c;在此之前简单了解下yum。 yum 介绍 yum&…

联系媒体要有方法莫让投稿发文章只剩一声长叹相见恨晚

曾有一位饱经世事的前辈以一句至理名言警醒世人:“人之所以领悟道理,往往不是源于抽象的道理本身,而是生活给予的实实在在的挫折教训,如同撞南墙一般的痛彻觉醒;同样,让人豁然开朗的,也不是空洞的说教,而是实实在在的人生磨砺。”这一哲理,放在我们日常工作中亦有深刻的启示作用…

困难样本挖掘:Hard Sample Mining(原理及实现)

Hard Sample Mining Hard Sample Mining&#xff0c;即困难样本挖掘&#xff0c;是目标检测中的一种常用方法。其主要思想是针对训练过程中损失较高的样本&#xff08;即那些难以被正确分类的样本&#xff09;进行挖掘&#xff0c;并将其补充到数据集中重新训练&#xff0c;以…

【Qt 学习笔记】Qt 背景介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt 背景介绍 文章编号&#xff1a;Qt 学习笔记 / 01 文章目录 Qt 背景…

配置plsql链接Oracle数据库(新手)

配置plsql链接Oracle数据库 安装Oracle客户端 、安装plsql客户端并激活 配置tnsnames.ora文件&#xff08;路径D:\app\peter\Oracle\InstantClient\network\admin根据你的实际路径设置&#xff09; 配置文件如下 # tnsnames.ora Network Configuration File: D:\app\peter\O…

【CKA模拟题】一文教你用StorageClass轻松创建PV

题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetesYour task involves setting up storage components in a Kubernetes cluster. Follow these steps: Step 1: Create a Storage Class…

卡尔曼滤波笔记

资料&#xff1a;https://www.zhihu.com/question/47559783/answer/2988744371 https://www.zhihu.com/question/47559783 https://blog.csdn.net/seek97/article/details/120012667 一、基本思想 在对一个状态值进行估计的时候&#xff0c;如果想测量值更准&#xff0c;很自然…

“探秘数据结构:栈的奇妙魔力“

每日一言 兰有秀兮菊有芳&#xff0c;怀佳人兮不能忘。 —刘彻- 栈 栈的概念及结构 栈(Stack) &#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守…

vue3+vite 模板vue3-element-admin框架如何关闭当前页面跳转 tabs

使用模版: 有来开源组织 / vue3-element-admin 需要关闭的.vue 页面增加以下方法 //setup 里import {LocationQuery, useRoute, useRouter} from "vue-router"; const router useRouter(); function close() {console.log(|--router.currentRoute.value, router.cur…

【MySQL系列】使用 ALTER TABLE 语句修改表结构的方法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

每日一题 第六十三期 洛谷 树状数组模板

【模板】树状数组 1 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 x x x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 n , m n,m n,m&#xff0c;分别表示该数列数字的个数和操作的总个数。 第二…

4.2 JavaWeb Day05分层解耦

三层架构功能 controller层接收请求&#xff0c;响应数据&#xff0c;层内调用了service层的方法&#xff0c;service层仅负责业务逻辑处理&#xff0c;其中要获取数据&#xff0c;就要去调用dao层&#xff0c;由dao层进行数据访问操作去查询数据&#xff08;进行增删改查&…

YOLOv8结合SCI低光照图像增强算法!让夜晚目标无处遁形!【含端到端推理脚本】

这里的"SCI"代表的并不是论文等级,而是论文采用的方法 — “自校准光照学习” ~ 左侧为SCI模型增强后图片的检测效果,右侧为原始v8n检测效果 这篇文章的主要内容是通过使用SCI模型和YOLOv8进行算法联调,最终实现了如上所示的效果:在增强图像可见度的同时,对图像…

Scala中如何使用Jsoup库处理HTML文档?

在当今互联网时代&#xff0c;数据是互联网应用程序的核心。对于开发者来说&#xff0c;获取并处理数据是日常工作中的重要一环。本文将介绍如何利用Scala中强大的Jsoup库进行网络请求和HTML解析&#xff0c;从而实现爬取京东网站的数据&#xff0c;让我们一起来探索吧&#xf…

【容易不简单】love 2d Lua 俄罗斯方块超详细教程

源码已经更新在CSDN的码库里&#xff1a; git clone https://gitcode.com/funsion/love2d-game.git 一直在找Lua 能快速便捷实现图形界面的软件&#xff0c;找了一堆&#xff0c;终于发现love2d是小而美的原生lua图形界面实现的方式。 并参考相关教程做了一个更详细的&#x…