Javascript DRY 模式 - 函数

标签 javascript design-patterns dry

面向对象新手,我正在制作一个游戏,我将其作为我的initialState:

let initialState = {
  grid : null,
  player : {
    coordinates : null,
    health : 100 ,
    weapon : "Stick",
    expLevel : 1
  },
  enemies : [],
  weapons : [],
  items : []
}

加载 DOM 后,我可以正确初始化weaponsitems。但是,除了初始化的对象文字之外,这两个属性共享确切的功能:

initialState.weapons = placeWeapons(3);
initialState.items = placeItems(2);

哪里 放置武器

function placeWeapons(numberofWeapons){
  let weapons = [];
  let availableSpots = [];
  let placementWeapons = []; //list of coordinates that will place weapons
  let grid = initialState.grid;

  //collect whats available of coords that are not taken in initialState.occupiedCoordinates
  grid.forEach( (row, rowIndex) => (
    row.forEach( (cell, colIndex) => {
      if (cell === 1){
        availableSpots.push([rowIndex,colIndex])
      }
    })
  ))

  //lets place the weapons. When placed, it will update initialState.occupiedCoordinates
  while( placementWeapons.length < numberofWeapons ){
    let randCoords = availableSpots[Math.floor(Math.random() * availableSpots.length)];
    if (grid[randCoords[0]][randCoords[1]] === 1){
      placementWeapons.push(randCoords);
      grid[randCoords[0]][randCoords[1]] = 0
    }
  }
  placementWeapons.forEach( coord => {
    let weapon = {
      name : "Weapon Name",
      coords : coord,
      damage : 3
    }
    weapons.push(weapon)
  })
  return weapons;
}

地点项目

function placeItems(numberofItems){
  let items = [];
  let availableSpots = [];
  let placementItems = []; //list of coordinates that will place items
  let grid = initialState.grid;

  //collect whats available of coords that are not taken in initialState.occupiedCoordinates
  grid.forEach( (row, rowIndex) => (
    row.forEach( (cell, colIndex) => {
      if (cell === 1){
        availableSpots.push([rowIndex,colIndex])
      }
    })
  ))

  //lets place the items. When placed, it will update initialState.occupiedCoordinates
  while( placementItems.length < numberofItems ){
    let randCoords = availableSpots[Math.floor(Math.random() * availableSpots.length)];
    if (grid[randCoords[0]][randCoords[1]] === 1){
      placementItems.push(randCoords);
      grid[randCoords[0]][randCoords[1]] = 0
    }
  }
  placementItems.forEach( coord => {
    let item = {
      name : "Item Name",
      coords : coord,
      health : 3
    }
    items.push(item)
  })
  return items;
}

我怎样才能干燥这个图案?

最佳答案

我看到的唯一显着差异是放置的东西。因此,合乎逻辑的做法是提取它并将其作为参数传递:

// WARNING: Untested code:
function placeThings(thing, numberofThings){
  let things = [];
  let availableSpots = [];
  let placementItems = []; //list of coordinates that will place things
  let grid = initialState.grid;

  //collect whats available of coords that are not taken in initialState.occupiedCoordinates
  grid.forEach( (row, rowIndex) => (
    row.forEach( (cell, colIndex) => {
      if (cell === 1){
        availableSpots.push([rowIndex,colIndex])
      }
    })
  ))

  //lets place the items. When placed, it will update initialState.occupiedCoordinates
  while( placementItems.length < numberofThings ){
    let randCoords = availableSpots[Math.floor(Math.random() * availableSpots.length)];
    if (grid[randCoords[0]][randCoords[1]] === 1){
      placementItems.push(randCoords);
      grid[randCoords[0]][randCoords[1]] = 0
    }
  }
  placementItems.forEach( coord => {
    things.push(Object.create(thing))
  })
  return things;
}

现在你可以做:

// Weapons:
placeThings({
  name : "Weapon Name",
  coords : coord,
  damage : 3
},50);

// Items:
placeThings({
  name : "Item Name",
  coords : coord,
  health : 3
},100);

如果你想让东西随机放置,你可以只传递一个函数而不是一个对象:

// WARNING: Untested code:
function placeThings(thingGenerator, numberofThings){
  let things = [];

  /*
   * bla bla..
   */

  placementItems.forEach( coord => {
    things.push(thingGenerator())
  })
  return things;
}

所以你会做这样的事情:

placeThings(makeWeapon, 50);
placeThings(makeItem, 100);

关于Javascript DRY 模式 - 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40371733/

相关文章:

jquery - "Don' t 重复自己”的 jQuery 菜单方法

javascript - react 或声明与功能

java - 解开 builder 模式的疑惑

ruby-on-rails - 类似查找查询的 DRY 实例变量

java - Java 的形状识别算法/代码

java - Pattern、Matcher、replace的用法

c# - 如果两个功能几乎相同,如何遵守 DRY 原则?

javascript - 在 Electron 应用程序中运行 Nightmare js 脚本

javascript - 如何使用javascript聚焦图像?

javascript - Nicedit 在 Chrome 中粘贴格式